n8n-editor-ui 1.67.0 → 1.69.0
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/dist/assets/AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-RSY0bJ42.js +57 -0
- package/dist/assets/{AuthView-DmC24d7S.js → AuthView-CrxWnr-e.js} +1 -1
- package/dist/assets/CanvasChat-D1ZEiEqI.js +4167 -0
- package/dist/assets/CanvasChat-DKeWqqZz.css +730 -0
- package/dist/assets/{CanvasControls-BPXQqeeO.js → CanvasControls-C-GYIweg.js} +6 -5
- package/dist/assets/{ChangePasswordView-SC3n2vJc.js → ChangePasswordView-BcJsOCsw.js} +2 -2
- package/dist/assets/CollectionParameter-BCa4NW-h.js +4 -0
- package/dist/assets/{CredentialsView-B3m9CpEC.js → CredentialsView-C0lKel2q.js} +12 -28
- package/dist/assets/{ErrorView-D6M8WlVP.js → ErrorView-4g2OU1Dw.js} +5 -4
- package/dist/assets/{ExecutionsFilter-DlZH8tDW.js → ExecutionsTime.vue_vue_type_script_setup_true_lang-Ce7AgzqR.js} +41 -41
- package/dist/assets/{ExecutionsView-DaHtYmF4.js → ExecutionsView-BjrC38YB.js} +28 -37
- package/dist/assets/{ExecutionsView-Dfy6JMwb.css → ExecutionsView-DlxsqdiC.css} +44 -38
- package/dist/assets/{FileSaver.min-DNytcjKT.js → FileSaver.min-Kzijnshy.js} +1 -1
- package/dist/assets/{FixedCollectionParameter-CypxYAFK.js → FixedCollectionParameter-BlCn1bdn.js} +1 -1
- package/dist/assets/{ForgotMyPasswordView-BJ6gd5CS.js → ForgotMyPasswordView-DM0y4hNn.js} +2 -2
- package/dist/assets/{MainHeader-D56WYRMG.css → MainHeader-CgL_r4xK.css} +78 -24
- package/dist/assets/{MainHeader-DniXcGMK.js → MainHeader-D1PkO9vp.js} +154 -45
- package/dist/assets/{MainSidebar-NwOfijmV.js → MainSidebar-CGlOacQQ.js} +63 -134
- package/dist/assets/{MainSidebar-BRYJRpOA.css → MainSidebar-DL53w2zU.css} +37 -21
- package/dist/assets/{NodeCreation-Ce1ct2i3.js → NodeCreation-yT3JgYis.js} +15 -11
- package/dist/assets/{NodeCreator-DMLTbzAt.js → NodeCreator-CeYHZgYz.js} +66 -64
- package/dist/assets/{NodeViewSwitcher-B9JUn3eY.js → NodeViewSwitcher-DJ9GWTwy.js} +2913 -2815
- package/dist/assets/{NodeViewSwitcher-CnP5aYyg.css → NodeViewSwitcher-s2TUlOvE.css} +136 -115
- package/dist/assets/{ProjectCardBadge-C3QU-WmO.js → ProjectCardBadge-dGORr1ye.js} +1 -1
- package/dist/assets/ProjectHeader-CFoxyI0_.js +216 -0
- package/dist/assets/ProjectHeader-CTK_rV3h.css +28 -0
- package/dist/assets/{ProjectSettings-BvcEg3hx.js → ProjectSettings-Bgl_JGoT.js} +27 -55
- package/dist/assets/{PushConnectionTracker.vue_vue_type_script_setup_true_lang-DlJOpf7N.js → PushConnectionTracker.vue_vue_type_script_setup_true_lang-BabWwsdK.js} +1 -1
- package/dist/assets/{ResourcesListLayout-Bc4__nvw.js → ResourcesListLayout-B1KB8fTB.js} +3 -46
- package/dist/assets/{ResourcesListLayout-Ci-K1bH3.css → ResourcesListLayout-BuxiQpsj.css} +8 -8
- package/dist/assets/{RunDataJson-ea5u1EeD.js → RunDataJson-BQRWHoEA.js} +12 -12
- package/dist/assets/{RunDataJsonActions-Dflnt8gK.js → RunDataJsonActions-BrABJ_1T.js} +3 -1
- package/dist/assets/{RunDataSearch-DKNVmEqa.js → RunDataSearch-kYhI-gst.js} +2 -2
- package/dist/assets/RunDataTable-BUXF-nH1.js +673 -0
- package/dist/assets/{RunDataTable-ZwoYenSI.css → RunDataTable-enskmmU4.css} +41 -35
- package/dist/assets/{SamlOnboarding-CPvGRYUg.js → SamlOnboarding-DI1aQpmq.js} +2 -2
- package/dist/assets/{SettingsApiView-BFj9fDL9.js → SettingsApiView-DfdFSKxW.js} +1 -1
- package/dist/assets/{SettingsCommunityNodesView-nJFDrtIR.js → SettingsCommunityNodesView-CFGZW601.js} +3 -3
- package/dist/assets/{SettingsExternalSecrets-0-mj45K-.js → SettingsExternalSecrets-CzMuyldc.js} +1 -1
- package/dist/assets/{SettingsLdapView-BhBxX72w.js → SettingsLdapView-B_aMpNa8.js} +1 -1
- package/dist/assets/{SettingsLogStreamingView-CmEJrEOv.js → SettingsLogStreamingView-ByHGVzc1.js} +1 -1
- package/dist/assets/{SettingsPersonalView-C__lC8Vv.js → SettingsPersonalView-BpmD5Kqd.js} +1 -1
- package/dist/assets/{SettingsSourceControl-CMoS5B5P.js → SettingsSourceControl-DeYPQUBX.js} +1 -1
- package/dist/assets/{SettingsSso-DJfrl1Rl.js → SettingsSso-1JSXMGCZ.js} +1 -1
- package/dist/assets/{SettingsUsageAndPlan-CWQ5uVrG.js → SettingsUsageAndPlan-CsUyzTgS.js} +1 -1
- package/dist/assets/{SettingsUsersView-Cvr6Digb.js → SettingsUsersView-iOvCX1d1.js} +1 -1
- package/dist/assets/{SettingsView-DtGga45F.js → SettingsView-WL2khukL.js} +1 -1
- package/dist/assets/{SetupView-DkJH96By.js → SetupView-CeWIEjRa.js} +2 -2
- package/dist/assets/{SetupWorkflowCredentialsButton-C1Jv_-V5.js → SetupWorkflowCredentialsButton-CqzxyhWQ.js} +1 -1
- package/dist/assets/{SetupWorkflowFromTemplateView-WSzVMgC4.js → SetupWorkflowFromTemplateView-HpPUcyfA.js} +3 -3
- package/dist/assets/{SigninView-xej8y-Vu.js → SigninView-DuDYUyp-.js} +2 -2
- package/dist/assets/{SignoutView-Dc8fBBIm.js → SignoutView-4gm8WRHv.js} +1 -1
- package/dist/assets/{SignupView-CKA28Xc8.js → SignupView-DjY8EclM.js} +2 -2
- package/dist/assets/{TemplateDetails-Pi49rFlS.js → TemplateDetails-CbfdJ3Zu.js} +2 -2
- package/dist/assets/{TemplateList-BncQL783.js → TemplateList-Cc_F6A58.js} +3 -2
- package/dist/assets/{TemplatesCollectionView-C9PKPo5y.js → TemplatesCollectionView-BcZLoIe4.js} +7 -7
- package/dist/assets/{TemplatesSearchView-65taIL-M.js → TemplatesSearchView-BMfAKWhL.js} +3 -3
- package/dist/assets/{TemplatesView-DkP9JWHk.js → TemplatesView-BP0ATqW_.js} +3 -2
- package/dist/assets/{TemplatesWorkflowView-B5uc0BtL.js → TemplatesWorkflowView-CPkYdvfj.js} +5 -5
- package/dist/assets/{VariablesView-DV1-KgmN.js → VariablesView-Bxnz2qAN.js} +12 -13
- package/dist/assets/{VariablesView-BPKo50HJ.css → VariablesView-meR15bnW.css} +18 -18
- package/dist/assets/{WorkerView-5P9lg6ew.js → WorkerView-DReO6N8w.js} +11 -10
- package/dist/assets/{WorkflowActivator-Dc_Un-Af.js → WorkflowActivator-B0RYBWDC.js} +2 -2
- package/dist/assets/{WorkflowExecutionsInfoAccordion-BLyC6lr5.js → WorkflowExecutionsInfoAccordion-DQl3QT6U.js} +7 -6
- package/dist/assets/{WorkflowExecutionsLandingPage-Dsa6Bgkn.js → WorkflowExecutionsLandingPage-B47g0omt.js} +2 -2
- package/dist/assets/{WorkflowExecutionsPreview-B_X-enUV.js → WorkflowExecutionsPreview-3ZPhGB00.js} +12 -11
- package/dist/assets/{WorkflowExecutionsView-Bkz3Sig-.js → WorkflowExecutionsView-C2F5tFjz.js} +18 -9
- package/dist/assets/{WorkflowExecutionsView-B8x2-iOd.css → WorkflowExecutionsView-CepgQyRt.css} +9 -1
- package/dist/assets/{WorkflowHistory-BiPMooAv.js → WorkflowHistory-tThywxbZ.js} +3 -3
- package/dist/assets/{WorkflowOnboardingView-XHuS6lCs.js → WorkflowOnboardingView-DJv_JU2k.js} +32 -1
- package/dist/assets/{WorkflowPreview-DxZKd23H.js → WorkflowPreview-DawY1Fi4.js} +1 -1
- package/dist/assets/{WorkflowsView-BBaLVqJs.js → WorkflowsView-DA1gqPuM.js} +16 -58
- package/dist/assets/buttons.esm-BOkmSohe.js +477 -0
- package/dist/assets/{index-7YFQEQmt.js → index-BcRlEQdt.js} +96643 -102180
- package/dist/assets/{index-BFH_KxyA.css → index-CSJeF569.css} +259 -726
- package/dist/assets/{pushConnection.store-DbprXL-x.js → pushConnection.store-C9cp1cmF.js} +1 -1
- package/dist/assets/{templateActions-QFQD8amJ.js → templateActions-BM1BlED1.js} +1 -1
- package/dist/assets/{useBugReporting-IgwBNdXI.js → useBugReporting-D4ibEI2f.js} +1 -1
- package/dist/assets/{useExecutionDebugging-CLORI_Ma.js → useExecutionDebugging-B9k8m7iG.js} +1 -1
- package/dist/assets/useExecutionHelpers-DYE5_K78.js +113 -0
- package/dist/assets/useGlobalEntityCreation-DtWHHZf8.js +168 -0
- package/dist/assets/{useNodeViewVersionSwitcher-CJLQ5lju.js → useNodeViewVersionSwitcher-CSLoLUvW.js} +1 -1
- package/dist/assets/{usePushConnection-DjPgTuLw.js → usePushConnection-BLi9GBVo.js} +63 -111
- package/dist/assets/{RunDataAi-x30tU8-0.css → useRunWorkflow-DH7ZzA8t.css} +97 -57
- package/dist/assets/useRunWorkflow-DOJBXbbW.js +3631 -0
- package/dist/assets/{useWorkflowActivate-D_gK841h.js → useWorkflowActivate-DmBELETa.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/assets/AnnotationTagsDropdown.ee.vue_vue_type_script_setup_true_lang-DbabN_I2.js +0 -115
- package/dist/assets/CollectionParameter-Odk28FRT.js +0 -4
- package/dist/assets/ProjectTabs-DjoIePoM.css +0 -3
- package/dist/assets/ProjectTabs-Dve3xFj9.js +0 -88
- package/dist/assets/ResourceListHeader-B2sxe6HT.js +0 -66
- package/dist/assets/ResourceListHeader-DgE1VPUF.css +0 -19
- package/dist/assets/RunDataAi-BKu1beM6.js +0 -1539
- package/dist/assets/RunDataTable-DISLWxMc.js +0 -608
- package/dist/assets/dateFormatter-C53K7zEn.js +0 -21
- /package/dist/assets/{ExecutionsFilter-DVxRt-Pz.css → ExecutionsTime-DVxRt-Pz.css} +0 -0
|
@@ -0,0 +1,4167 @@
|
|
|
1
|
+
import { aP as inject, aQ as isRef, c as openBlock, h as createElementBlock, j as createBaseVNode, d as defineComponent, q as computed, i as createVNode, l as unref, t as toDisplayString, I as withModifiers, e as createBlock, f as createCommentVNode, _ as _export_sfc, aR as toRefs, r as ref, o as onMounted, s as renderSlot, aS as normalizeProps, aT as guardReactiveProps, aU as mergeProps, aV as resolveDynamicComponent, aW as VueMarkdown, F as Fragment, A as renderList, n as normalizeClass, aX as markdownLink, aY as useFileDialog, aZ as onUnmounted, ax as withDirectives, a_ as vModelText, G as withKeys, B as normalizeStyle, w as withCtx, H as watch, m as resolveComponent, k as createTextVNode, a$ as useClipboard, a as useToast, g as useI18n$1, ae as MODAL_CONFIRM, al as useMessage, b0 as CHAT_TRIGGER_NODE_TYPE, b1 as MANUAL_CHAT_TRIGGER_NODE_TYPE, b2 as CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE, b3 as AI_SUBCATEGORY, b4 as AI_CATEGORY_AGENTS, b5 as AI_CATEGORY_CHAINS, b6 as AI_CODE_NODE_TYPE, b7 as getNodeInputs, b8 as getConnectionTypes, b9 as getNodeOutputs, ba as NodeConnectionType, bb as get, bc as v4, bd as isEmpty, be as last, bf as CHAT_TRIGGER_NODE_TYPE$1, aF as useStorage, bg as watchEffect, x as onBeforeUnmount, J as useDebounce, T as useWorkflowsStore, K as useUIStore, $ as useCanvasStore, bh as useNodeTypesStore, bi as useNodeHelpers, b as useRouter, V as VIEWS, bj as provide } from "./index-BcRlEQdt.js";
|
|
2
|
+
import { H as HighlightJS, R as RunDataAi, u as usePinnedData, a as useRunWorkflow } from "./useRunWorkflow-DOJBXbbW.js";
|
|
3
|
+
import "./useExecutionHelpers-DYE5_K78.js";
|
|
4
|
+
const ChatSymbol = "Chat";
|
|
5
|
+
const ChatOptionsSymbol = "ChatOptions";
|
|
6
|
+
function createEventBus() {
|
|
7
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
8
|
+
function off(eventName, fn) {
|
|
9
|
+
const eventFns = handlers.get(eventName);
|
|
10
|
+
if (eventFns) {
|
|
11
|
+
eventFns.splice(eventFns.indexOf(fn) >>> 0, 1);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function on(eventName, fn) {
|
|
15
|
+
let eventFns = handlers.get(eventName);
|
|
16
|
+
if (!eventFns) {
|
|
17
|
+
eventFns = [fn];
|
|
18
|
+
} else {
|
|
19
|
+
eventFns.push(fn);
|
|
20
|
+
}
|
|
21
|
+
handlers.set(eventName, eventFns);
|
|
22
|
+
return () => off(eventName, fn);
|
|
23
|
+
}
|
|
24
|
+
function emit(eventName, event) {
|
|
25
|
+
const eventFns = handlers.get(eventName);
|
|
26
|
+
if (eventFns) {
|
|
27
|
+
eventFns.slice().forEach(async (handler) => {
|
|
28
|
+
await handler(event);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
on,
|
|
34
|
+
off,
|
|
35
|
+
emit
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const chatEventBus = createEventBus();
|
|
39
|
+
function bash(hljs) {
|
|
40
|
+
const regex = hljs.regex;
|
|
41
|
+
const VAR = {};
|
|
42
|
+
const BRACED_VAR = {
|
|
43
|
+
begin: /\$\{/,
|
|
44
|
+
end: /\}/,
|
|
45
|
+
contains: [
|
|
46
|
+
"self",
|
|
47
|
+
{
|
|
48
|
+
begin: /:-/,
|
|
49
|
+
contains: [VAR]
|
|
50
|
+
}
|
|
51
|
+
// default values
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
Object.assign(VAR, {
|
|
55
|
+
className: "variable",
|
|
56
|
+
variants: [
|
|
57
|
+
{ begin: regex.concat(
|
|
58
|
+
/\$[\w\d#@][\w\d_]*/,
|
|
59
|
+
// negative look-ahead tries to avoid matching patterns that are not
|
|
60
|
+
// Perl at all like $ident$, @ident@, etc.
|
|
61
|
+
`(?![\\w\\d])(?![$])`
|
|
62
|
+
) },
|
|
63
|
+
BRACED_VAR
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
const SUBST = {
|
|
67
|
+
className: "subst",
|
|
68
|
+
begin: /\$\(/,
|
|
69
|
+
end: /\)/,
|
|
70
|
+
contains: [hljs.BACKSLASH_ESCAPE]
|
|
71
|
+
};
|
|
72
|
+
const HERE_DOC = {
|
|
73
|
+
begin: /<<-?\s*(?=\w+)/,
|
|
74
|
+
starts: { contains: [
|
|
75
|
+
hljs.END_SAME_AS_BEGIN({
|
|
76
|
+
begin: /(\w+)/,
|
|
77
|
+
end: /(\w+)/,
|
|
78
|
+
className: "string"
|
|
79
|
+
})
|
|
80
|
+
] }
|
|
81
|
+
};
|
|
82
|
+
const QUOTE_STRING = {
|
|
83
|
+
className: "string",
|
|
84
|
+
begin: /"/,
|
|
85
|
+
end: /"/,
|
|
86
|
+
contains: [
|
|
87
|
+
hljs.BACKSLASH_ESCAPE,
|
|
88
|
+
VAR,
|
|
89
|
+
SUBST
|
|
90
|
+
]
|
|
91
|
+
};
|
|
92
|
+
SUBST.contains.push(QUOTE_STRING);
|
|
93
|
+
const ESCAPED_QUOTE = {
|
|
94
|
+
match: /\\"/
|
|
95
|
+
};
|
|
96
|
+
const APOS_STRING = {
|
|
97
|
+
className: "string",
|
|
98
|
+
begin: /'/,
|
|
99
|
+
end: /'/
|
|
100
|
+
};
|
|
101
|
+
const ESCAPED_APOS = {
|
|
102
|
+
match: /\\'/
|
|
103
|
+
};
|
|
104
|
+
const ARITHMETIC = {
|
|
105
|
+
begin: /\$?\(\(/,
|
|
106
|
+
end: /\)\)/,
|
|
107
|
+
contains: [
|
|
108
|
+
{
|
|
109
|
+
begin: /\d+#[0-9a-f]+/,
|
|
110
|
+
className: "number"
|
|
111
|
+
},
|
|
112
|
+
hljs.NUMBER_MODE,
|
|
113
|
+
VAR
|
|
114
|
+
]
|
|
115
|
+
};
|
|
116
|
+
const SH_LIKE_SHELLS = [
|
|
117
|
+
"fish",
|
|
118
|
+
"bash",
|
|
119
|
+
"zsh",
|
|
120
|
+
"sh",
|
|
121
|
+
"csh",
|
|
122
|
+
"ksh",
|
|
123
|
+
"tcsh",
|
|
124
|
+
"dash",
|
|
125
|
+
"scsh"
|
|
126
|
+
];
|
|
127
|
+
const KNOWN_SHEBANG = hljs.SHEBANG({
|
|
128
|
+
binary: `(${SH_LIKE_SHELLS.join("|")})`,
|
|
129
|
+
relevance: 10
|
|
130
|
+
});
|
|
131
|
+
const FUNCTION = {
|
|
132
|
+
className: "function",
|
|
133
|
+
begin: /\w[\w\d_]*\s*\(\s*\)\s*\{/,
|
|
134
|
+
returnBegin: true,
|
|
135
|
+
contains: [hljs.inherit(hljs.TITLE_MODE, { begin: /\w[\w\d_]*/ })],
|
|
136
|
+
relevance: 0
|
|
137
|
+
};
|
|
138
|
+
const KEYWORDS2 = [
|
|
139
|
+
"if",
|
|
140
|
+
"then",
|
|
141
|
+
"else",
|
|
142
|
+
"elif",
|
|
143
|
+
"fi",
|
|
144
|
+
"for",
|
|
145
|
+
"while",
|
|
146
|
+
"until",
|
|
147
|
+
"in",
|
|
148
|
+
"do",
|
|
149
|
+
"done",
|
|
150
|
+
"case",
|
|
151
|
+
"esac",
|
|
152
|
+
"function",
|
|
153
|
+
"select"
|
|
154
|
+
];
|
|
155
|
+
const LITERALS2 = [
|
|
156
|
+
"true",
|
|
157
|
+
"false"
|
|
158
|
+
];
|
|
159
|
+
const PATH_MODE = { match: /(\/[a-z._-]+)+/ };
|
|
160
|
+
const SHELL_BUILT_INS = [
|
|
161
|
+
"break",
|
|
162
|
+
"cd",
|
|
163
|
+
"continue",
|
|
164
|
+
"eval",
|
|
165
|
+
"exec",
|
|
166
|
+
"exit",
|
|
167
|
+
"export",
|
|
168
|
+
"getopts",
|
|
169
|
+
"hash",
|
|
170
|
+
"pwd",
|
|
171
|
+
"readonly",
|
|
172
|
+
"return",
|
|
173
|
+
"shift",
|
|
174
|
+
"test",
|
|
175
|
+
"times",
|
|
176
|
+
"trap",
|
|
177
|
+
"umask",
|
|
178
|
+
"unset"
|
|
179
|
+
];
|
|
180
|
+
const BASH_BUILT_INS = [
|
|
181
|
+
"alias",
|
|
182
|
+
"bind",
|
|
183
|
+
"builtin",
|
|
184
|
+
"caller",
|
|
185
|
+
"command",
|
|
186
|
+
"declare",
|
|
187
|
+
"echo",
|
|
188
|
+
"enable",
|
|
189
|
+
"help",
|
|
190
|
+
"let",
|
|
191
|
+
"local",
|
|
192
|
+
"logout",
|
|
193
|
+
"mapfile",
|
|
194
|
+
"printf",
|
|
195
|
+
"read",
|
|
196
|
+
"readarray",
|
|
197
|
+
"source",
|
|
198
|
+
"type",
|
|
199
|
+
"typeset",
|
|
200
|
+
"ulimit",
|
|
201
|
+
"unalias"
|
|
202
|
+
];
|
|
203
|
+
const ZSH_BUILT_INS = [
|
|
204
|
+
"autoload",
|
|
205
|
+
"bg",
|
|
206
|
+
"bindkey",
|
|
207
|
+
"bye",
|
|
208
|
+
"cap",
|
|
209
|
+
"chdir",
|
|
210
|
+
"clone",
|
|
211
|
+
"comparguments",
|
|
212
|
+
"compcall",
|
|
213
|
+
"compctl",
|
|
214
|
+
"compdescribe",
|
|
215
|
+
"compfiles",
|
|
216
|
+
"compgroups",
|
|
217
|
+
"compquote",
|
|
218
|
+
"comptags",
|
|
219
|
+
"comptry",
|
|
220
|
+
"compvalues",
|
|
221
|
+
"dirs",
|
|
222
|
+
"disable",
|
|
223
|
+
"disown",
|
|
224
|
+
"echotc",
|
|
225
|
+
"echoti",
|
|
226
|
+
"emulate",
|
|
227
|
+
"fc",
|
|
228
|
+
"fg",
|
|
229
|
+
"float",
|
|
230
|
+
"functions",
|
|
231
|
+
"getcap",
|
|
232
|
+
"getln",
|
|
233
|
+
"history",
|
|
234
|
+
"integer",
|
|
235
|
+
"jobs",
|
|
236
|
+
"kill",
|
|
237
|
+
"limit",
|
|
238
|
+
"log",
|
|
239
|
+
"noglob",
|
|
240
|
+
"popd",
|
|
241
|
+
"print",
|
|
242
|
+
"pushd",
|
|
243
|
+
"pushln",
|
|
244
|
+
"rehash",
|
|
245
|
+
"sched",
|
|
246
|
+
"setcap",
|
|
247
|
+
"setopt",
|
|
248
|
+
"stat",
|
|
249
|
+
"suspend",
|
|
250
|
+
"ttyctl",
|
|
251
|
+
"unfunction",
|
|
252
|
+
"unhash",
|
|
253
|
+
"unlimit",
|
|
254
|
+
"unsetopt",
|
|
255
|
+
"vared",
|
|
256
|
+
"wait",
|
|
257
|
+
"whence",
|
|
258
|
+
"where",
|
|
259
|
+
"which",
|
|
260
|
+
"zcompile",
|
|
261
|
+
"zformat",
|
|
262
|
+
"zftp",
|
|
263
|
+
"zle",
|
|
264
|
+
"zmodload",
|
|
265
|
+
"zparseopts",
|
|
266
|
+
"zprof",
|
|
267
|
+
"zpty",
|
|
268
|
+
"zregexparse",
|
|
269
|
+
"zsocket",
|
|
270
|
+
"zstyle",
|
|
271
|
+
"ztcp"
|
|
272
|
+
];
|
|
273
|
+
const GNU_CORE_UTILS = [
|
|
274
|
+
"chcon",
|
|
275
|
+
"chgrp",
|
|
276
|
+
"chown",
|
|
277
|
+
"chmod",
|
|
278
|
+
"cp",
|
|
279
|
+
"dd",
|
|
280
|
+
"df",
|
|
281
|
+
"dir",
|
|
282
|
+
"dircolors",
|
|
283
|
+
"ln",
|
|
284
|
+
"ls",
|
|
285
|
+
"mkdir",
|
|
286
|
+
"mkfifo",
|
|
287
|
+
"mknod",
|
|
288
|
+
"mktemp",
|
|
289
|
+
"mv",
|
|
290
|
+
"realpath",
|
|
291
|
+
"rm",
|
|
292
|
+
"rmdir",
|
|
293
|
+
"shred",
|
|
294
|
+
"sync",
|
|
295
|
+
"touch",
|
|
296
|
+
"truncate",
|
|
297
|
+
"vdir",
|
|
298
|
+
"b2sum",
|
|
299
|
+
"base32",
|
|
300
|
+
"base64",
|
|
301
|
+
"cat",
|
|
302
|
+
"cksum",
|
|
303
|
+
"comm",
|
|
304
|
+
"csplit",
|
|
305
|
+
"cut",
|
|
306
|
+
"expand",
|
|
307
|
+
"fmt",
|
|
308
|
+
"fold",
|
|
309
|
+
"head",
|
|
310
|
+
"join",
|
|
311
|
+
"md5sum",
|
|
312
|
+
"nl",
|
|
313
|
+
"numfmt",
|
|
314
|
+
"od",
|
|
315
|
+
"paste",
|
|
316
|
+
"ptx",
|
|
317
|
+
"pr",
|
|
318
|
+
"sha1sum",
|
|
319
|
+
"sha224sum",
|
|
320
|
+
"sha256sum",
|
|
321
|
+
"sha384sum",
|
|
322
|
+
"sha512sum",
|
|
323
|
+
"shuf",
|
|
324
|
+
"sort",
|
|
325
|
+
"split",
|
|
326
|
+
"sum",
|
|
327
|
+
"tac",
|
|
328
|
+
"tail",
|
|
329
|
+
"tr",
|
|
330
|
+
"tsort",
|
|
331
|
+
"unexpand",
|
|
332
|
+
"uniq",
|
|
333
|
+
"wc",
|
|
334
|
+
"arch",
|
|
335
|
+
"basename",
|
|
336
|
+
"chroot",
|
|
337
|
+
"date",
|
|
338
|
+
"dirname",
|
|
339
|
+
"du",
|
|
340
|
+
"echo",
|
|
341
|
+
"env",
|
|
342
|
+
"expr",
|
|
343
|
+
"factor",
|
|
344
|
+
// "false", // keyword literal already
|
|
345
|
+
"groups",
|
|
346
|
+
"hostid",
|
|
347
|
+
"id",
|
|
348
|
+
"link",
|
|
349
|
+
"logname",
|
|
350
|
+
"nice",
|
|
351
|
+
"nohup",
|
|
352
|
+
"nproc",
|
|
353
|
+
"pathchk",
|
|
354
|
+
"pinky",
|
|
355
|
+
"printenv",
|
|
356
|
+
"printf",
|
|
357
|
+
"pwd",
|
|
358
|
+
"readlink",
|
|
359
|
+
"runcon",
|
|
360
|
+
"seq",
|
|
361
|
+
"sleep",
|
|
362
|
+
"stat",
|
|
363
|
+
"stdbuf",
|
|
364
|
+
"stty",
|
|
365
|
+
"tee",
|
|
366
|
+
"test",
|
|
367
|
+
"timeout",
|
|
368
|
+
// "true", // keyword literal already
|
|
369
|
+
"tty",
|
|
370
|
+
"uname",
|
|
371
|
+
"unlink",
|
|
372
|
+
"uptime",
|
|
373
|
+
"users",
|
|
374
|
+
"who",
|
|
375
|
+
"whoami",
|
|
376
|
+
"yes"
|
|
377
|
+
];
|
|
378
|
+
return {
|
|
379
|
+
name: "Bash",
|
|
380
|
+
aliases: ["sh"],
|
|
381
|
+
keywords: {
|
|
382
|
+
$pattern: /\b[a-z][a-z0-9._-]+\b/,
|
|
383
|
+
keyword: KEYWORDS2,
|
|
384
|
+
literal: LITERALS2,
|
|
385
|
+
built_in: [
|
|
386
|
+
...SHELL_BUILT_INS,
|
|
387
|
+
...BASH_BUILT_INS,
|
|
388
|
+
// Shell modifiers
|
|
389
|
+
"set",
|
|
390
|
+
"shopt",
|
|
391
|
+
...ZSH_BUILT_INS,
|
|
392
|
+
...GNU_CORE_UTILS
|
|
393
|
+
]
|
|
394
|
+
},
|
|
395
|
+
contains: [
|
|
396
|
+
KNOWN_SHEBANG,
|
|
397
|
+
// to catch known shells and boost relevancy
|
|
398
|
+
hljs.SHEBANG(),
|
|
399
|
+
// to catch unknown shells but still highlight the shebang
|
|
400
|
+
FUNCTION,
|
|
401
|
+
ARITHMETIC,
|
|
402
|
+
hljs.HASH_COMMENT_MODE,
|
|
403
|
+
HERE_DOC,
|
|
404
|
+
PATH_MODE,
|
|
405
|
+
QUOTE_STRING,
|
|
406
|
+
ESCAPED_QUOTE,
|
|
407
|
+
APOS_STRING,
|
|
408
|
+
ESCAPED_APOS,
|
|
409
|
+
VAR
|
|
410
|
+
]
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
const IDENT_RE$1 = "[A-Za-z$_][0-9A-Za-z$_]*";
|
|
414
|
+
const KEYWORDS$1 = [
|
|
415
|
+
"as",
|
|
416
|
+
// for exports
|
|
417
|
+
"in",
|
|
418
|
+
"of",
|
|
419
|
+
"if",
|
|
420
|
+
"for",
|
|
421
|
+
"while",
|
|
422
|
+
"finally",
|
|
423
|
+
"var",
|
|
424
|
+
"new",
|
|
425
|
+
"function",
|
|
426
|
+
"do",
|
|
427
|
+
"return",
|
|
428
|
+
"void",
|
|
429
|
+
"else",
|
|
430
|
+
"break",
|
|
431
|
+
"catch",
|
|
432
|
+
"instanceof",
|
|
433
|
+
"with",
|
|
434
|
+
"throw",
|
|
435
|
+
"case",
|
|
436
|
+
"default",
|
|
437
|
+
"try",
|
|
438
|
+
"switch",
|
|
439
|
+
"continue",
|
|
440
|
+
"typeof",
|
|
441
|
+
"delete",
|
|
442
|
+
"let",
|
|
443
|
+
"yield",
|
|
444
|
+
"const",
|
|
445
|
+
"class",
|
|
446
|
+
// JS handles these with a special rule
|
|
447
|
+
// "get",
|
|
448
|
+
// "set",
|
|
449
|
+
"debugger",
|
|
450
|
+
"async",
|
|
451
|
+
"await",
|
|
452
|
+
"static",
|
|
453
|
+
"import",
|
|
454
|
+
"from",
|
|
455
|
+
"export",
|
|
456
|
+
"extends"
|
|
457
|
+
];
|
|
458
|
+
const LITERALS$1 = [
|
|
459
|
+
"true",
|
|
460
|
+
"false",
|
|
461
|
+
"null",
|
|
462
|
+
"undefined",
|
|
463
|
+
"NaN",
|
|
464
|
+
"Infinity"
|
|
465
|
+
];
|
|
466
|
+
const TYPES$1 = [
|
|
467
|
+
// Fundamental objects
|
|
468
|
+
"Object",
|
|
469
|
+
"Function",
|
|
470
|
+
"Boolean",
|
|
471
|
+
"Symbol",
|
|
472
|
+
// numbers and dates
|
|
473
|
+
"Math",
|
|
474
|
+
"Date",
|
|
475
|
+
"Number",
|
|
476
|
+
"BigInt",
|
|
477
|
+
// text
|
|
478
|
+
"String",
|
|
479
|
+
"RegExp",
|
|
480
|
+
// Indexed collections
|
|
481
|
+
"Array",
|
|
482
|
+
"Float32Array",
|
|
483
|
+
"Float64Array",
|
|
484
|
+
"Int8Array",
|
|
485
|
+
"Uint8Array",
|
|
486
|
+
"Uint8ClampedArray",
|
|
487
|
+
"Int16Array",
|
|
488
|
+
"Int32Array",
|
|
489
|
+
"Uint16Array",
|
|
490
|
+
"Uint32Array",
|
|
491
|
+
"BigInt64Array",
|
|
492
|
+
"BigUint64Array",
|
|
493
|
+
// Keyed collections
|
|
494
|
+
"Set",
|
|
495
|
+
"Map",
|
|
496
|
+
"WeakSet",
|
|
497
|
+
"WeakMap",
|
|
498
|
+
// Structured data
|
|
499
|
+
"ArrayBuffer",
|
|
500
|
+
"SharedArrayBuffer",
|
|
501
|
+
"Atomics",
|
|
502
|
+
"DataView",
|
|
503
|
+
"JSON",
|
|
504
|
+
// Control abstraction objects
|
|
505
|
+
"Promise",
|
|
506
|
+
"Generator",
|
|
507
|
+
"GeneratorFunction",
|
|
508
|
+
"AsyncFunction",
|
|
509
|
+
// Reflection
|
|
510
|
+
"Reflect",
|
|
511
|
+
"Proxy",
|
|
512
|
+
// Internationalization
|
|
513
|
+
"Intl",
|
|
514
|
+
// WebAssembly
|
|
515
|
+
"WebAssembly"
|
|
516
|
+
];
|
|
517
|
+
const ERROR_TYPES$1 = [
|
|
518
|
+
"Error",
|
|
519
|
+
"EvalError",
|
|
520
|
+
"InternalError",
|
|
521
|
+
"RangeError",
|
|
522
|
+
"ReferenceError",
|
|
523
|
+
"SyntaxError",
|
|
524
|
+
"TypeError",
|
|
525
|
+
"URIError"
|
|
526
|
+
];
|
|
527
|
+
const BUILT_IN_GLOBALS$1 = [
|
|
528
|
+
"setInterval",
|
|
529
|
+
"setTimeout",
|
|
530
|
+
"clearInterval",
|
|
531
|
+
"clearTimeout",
|
|
532
|
+
"require",
|
|
533
|
+
"exports",
|
|
534
|
+
"eval",
|
|
535
|
+
"isFinite",
|
|
536
|
+
"isNaN",
|
|
537
|
+
"parseFloat",
|
|
538
|
+
"parseInt",
|
|
539
|
+
"decodeURI",
|
|
540
|
+
"decodeURIComponent",
|
|
541
|
+
"encodeURI",
|
|
542
|
+
"encodeURIComponent",
|
|
543
|
+
"escape",
|
|
544
|
+
"unescape"
|
|
545
|
+
];
|
|
546
|
+
const BUILT_IN_VARIABLES$1 = [
|
|
547
|
+
"arguments",
|
|
548
|
+
"this",
|
|
549
|
+
"super",
|
|
550
|
+
"console",
|
|
551
|
+
"window",
|
|
552
|
+
"document",
|
|
553
|
+
"localStorage",
|
|
554
|
+
"sessionStorage",
|
|
555
|
+
"module",
|
|
556
|
+
"global"
|
|
557
|
+
// Node.js
|
|
558
|
+
];
|
|
559
|
+
const BUILT_INS$1 = [].concat(
|
|
560
|
+
BUILT_IN_GLOBALS$1,
|
|
561
|
+
TYPES$1,
|
|
562
|
+
ERROR_TYPES$1
|
|
563
|
+
);
|
|
564
|
+
function javascript$1(hljs) {
|
|
565
|
+
const regex = hljs.regex;
|
|
566
|
+
const hasClosingTag = (match, { after }) => {
|
|
567
|
+
const tag = "</" + match[0].slice(1);
|
|
568
|
+
const pos = match.input.indexOf(tag, after);
|
|
569
|
+
return pos !== -1;
|
|
570
|
+
};
|
|
571
|
+
const IDENT_RE$1$1 = IDENT_RE$1;
|
|
572
|
+
const FRAGMENT = {
|
|
573
|
+
begin: "<>",
|
|
574
|
+
end: "</>"
|
|
575
|
+
};
|
|
576
|
+
const XML_SELF_CLOSING = /<[A-Za-z0-9\\._:-]+\s*\/>/;
|
|
577
|
+
const XML_TAG = {
|
|
578
|
+
begin: /<[A-Za-z0-9\\._:-]+/,
|
|
579
|
+
end: /\/[A-Za-z0-9\\._:-]+>|\/>/,
|
|
580
|
+
/**
|
|
581
|
+
* @param {RegExpMatchArray} match
|
|
582
|
+
* @param {CallbackResponse} response
|
|
583
|
+
*/
|
|
584
|
+
isTrulyOpeningTag: (match, response) => {
|
|
585
|
+
const afterMatchIndex = match[0].length + match.index;
|
|
586
|
+
const nextChar = match.input[afterMatchIndex];
|
|
587
|
+
if (
|
|
588
|
+
// HTML should not include another raw `<` inside a tag
|
|
589
|
+
// nested type?
|
|
590
|
+
// `<Array<Array<number>>`, etc.
|
|
591
|
+
nextChar === "<" || // the , gives away that this is not HTML
|
|
592
|
+
// `<T, A extends keyof T, V>`
|
|
593
|
+
nextChar === ","
|
|
594
|
+
) {
|
|
595
|
+
response.ignoreMatch();
|
|
596
|
+
return;
|
|
597
|
+
}
|
|
598
|
+
if (nextChar === ">") {
|
|
599
|
+
if (!hasClosingTag(match, { after: afterMatchIndex })) {
|
|
600
|
+
response.ignoreMatch();
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
let m;
|
|
604
|
+
const afterMatch = match.input.substring(afterMatchIndex);
|
|
605
|
+
if (m = afterMatch.match(/^\s*=/)) {
|
|
606
|
+
response.ignoreMatch();
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
if (m = afterMatch.match(/^\s+extends\s+/)) {
|
|
610
|
+
if (m.index === 0) {
|
|
611
|
+
response.ignoreMatch();
|
|
612
|
+
return;
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
};
|
|
617
|
+
const KEYWORDS$1$1 = {
|
|
618
|
+
$pattern: IDENT_RE$1,
|
|
619
|
+
keyword: KEYWORDS$1,
|
|
620
|
+
literal: LITERALS$1,
|
|
621
|
+
built_in: BUILT_INS$1,
|
|
622
|
+
"variable.language": BUILT_IN_VARIABLES$1
|
|
623
|
+
};
|
|
624
|
+
const decimalDigits = "[0-9](_?[0-9])*";
|
|
625
|
+
const frac = `\\.(${decimalDigits})`;
|
|
626
|
+
const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;
|
|
627
|
+
const NUMBER = {
|
|
628
|
+
className: "number",
|
|
629
|
+
variants: [
|
|
630
|
+
// DecimalLiteral
|
|
631
|
+
{ begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))[eE][+-]?(${decimalDigits})\\b` },
|
|
632
|
+
{ begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` },
|
|
633
|
+
// DecimalBigIntegerLiteral
|
|
634
|
+
{ begin: `\\b(0|[1-9](_?[0-9])*)n\\b` },
|
|
635
|
+
// NonDecimalIntegerLiteral
|
|
636
|
+
{ begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" },
|
|
637
|
+
{ begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" },
|
|
638
|
+
{ begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" },
|
|
639
|
+
// LegacyOctalIntegerLiteral (does not include underscore separators)
|
|
640
|
+
// https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals
|
|
641
|
+
{ begin: "\\b0[0-7]+n?\\b" }
|
|
642
|
+
],
|
|
643
|
+
relevance: 0
|
|
644
|
+
};
|
|
645
|
+
const SUBST = {
|
|
646
|
+
className: "subst",
|
|
647
|
+
begin: "\\$\\{",
|
|
648
|
+
end: "\\}",
|
|
649
|
+
keywords: KEYWORDS$1$1,
|
|
650
|
+
contains: []
|
|
651
|
+
// defined later
|
|
652
|
+
};
|
|
653
|
+
const HTML_TEMPLATE = {
|
|
654
|
+
begin: "html`",
|
|
655
|
+
end: "",
|
|
656
|
+
starts: {
|
|
657
|
+
end: "`",
|
|
658
|
+
returnEnd: false,
|
|
659
|
+
contains: [
|
|
660
|
+
hljs.BACKSLASH_ESCAPE,
|
|
661
|
+
SUBST
|
|
662
|
+
],
|
|
663
|
+
subLanguage: "xml"
|
|
664
|
+
}
|
|
665
|
+
};
|
|
666
|
+
const CSS_TEMPLATE = {
|
|
667
|
+
begin: "css`",
|
|
668
|
+
end: "",
|
|
669
|
+
starts: {
|
|
670
|
+
end: "`",
|
|
671
|
+
returnEnd: false,
|
|
672
|
+
contains: [
|
|
673
|
+
hljs.BACKSLASH_ESCAPE,
|
|
674
|
+
SUBST
|
|
675
|
+
],
|
|
676
|
+
subLanguage: "css"
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
const GRAPHQL_TEMPLATE = {
|
|
680
|
+
begin: "gql`",
|
|
681
|
+
end: "",
|
|
682
|
+
starts: {
|
|
683
|
+
end: "`",
|
|
684
|
+
returnEnd: false,
|
|
685
|
+
contains: [
|
|
686
|
+
hljs.BACKSLASH_ESCAPE,
|
|
687
|
+
SUBST
|
|
688
|
+
],
|
|
689
|
+
subLanguage: "graphql"
|
|
690
|
+
}
|
|
691
|
+
};
|
|
692
|
+
const TEMPLATE_STRING = {
|
|
693
|
+
className: "string",
|
|
694
|
+
begin: "`",
|
|
695
|
+
end: "`",
|
|
696
|
+
contains: [
|
|
697
|
+
hljs.BACKSLASH_ESCAPE,
|
|
698
|
+
SUBST
|
|
699
|
+
]
|
|
700
|
+
};
|
|
701
|
+
const JSDOC_COMMENT = hljs.COMMENT(
|
|
702
|
+
/\/\*\*(?!\/)/,
|
|
703
|
+
"\\*/",
|
|
704
|
+
{
|
|
705
|
+
relevance: 0,
|
|
706
|
+
contains: [
|
|
707
|
+
{
|
|
708
|
+
begin: "(?=@[A-Za-z]+)",
|
|
709
|
+
relevance: 0,
|
|
710
|
+
contains: [
|
|
711
|
+
{
|
|
712
|
+
className: "doctag",
|
|
713
|
+
begin: "@[A-Za-z]+"
|
|
714
|
+
},
|
|
715
|
+
{
|
|
716
|
+
className: "type",
|
|
717
|
+
begin: "\\{",
|
|
718
|
+
end: "\\}",
|
|
719
|
+
excludeEnd: true,
|
|
720
|
+
excludeBegin: true,
|
|
721
|
+
relevance: 0
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
className: "variable",
|
|
725
|
+
begin: IDENT_RE$1$1 + "(?=\\s*(-)|$)",
|
|
726
|
+
endsParent: true,
|
|
727
|
+
relevance: 0
|
|
728
|
+
},
|
|
729
|
+
// eat spaces (not newlines) so we can find
|
|
730
|
+
// types or variables
|
|
731
|
+
{
|
|
732
|
+
begin: /(?=[^\n])\s/,
|
|
733
|
+
relevance: 0
|
|
734
|
+
}
|
|
735
|
+
]
|
|
736
|
+
}
|
|
737
|
+
]
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
const COMMENT = {
|
|
741
|
+
className: "comment",
|
|
742
|
+
variants: [
|
|
743
|
+
JSDOC_COMMENT,
|
|
744
|
+
hljs.C_BLOCK_COMMENT_MODE,
|
|
745
|
+
hljs.C_LINE_COMMENT_MODE
|
|
746
|
+
]
|
|
747
|
+
};
|
|
748
|
+
const SUBST_INTERNALS = [
|
|
749
|
+
hljs.APOS_STRING_MODE,
|
|
750
|
+
hljs.QUOTE_STRING_MODE,
|
|
751
|
+
HTML_TEMPLATE,
|
|
752
|
+
CSS_TEMPLATE,
|
|
753
|
+
GRAPHQL_TEMPLATE,
|
|
754
|
+
TEMPLATE_STRING,
|
|
755
|
+
// Skip numbers when they are part of a variable name
|
|
756
|
+
{ match: /\$\d+/ },
|
|
757
|
+
NUMBER
|
|
758
|
+
// This is intentional:
|
|
759
|
+
// See https://github.com/highlightjs/highlight.js/issues/3288
|
|
760
|
+
// hljs.REGEXP_MODE
|
|
761
|
+
];
|
|
762
|
+
SUBST.contains = SUBST_INTERNALS.concat({
|
|
763
|
+
// we need to pair up {} inside our subst to prevent
|
|
764
|
+
// it from ending too early by matching another }
|
|
765
|
+
begin: /\{/,
|
|
766
|
+
end: /\}/,
|
|
767
|
+
keywords: KEYWORDS$1$1,
|
|
768
|
+
contains: [
|
|
769
|
+
"self"
|
|
770
|
+
].concat(SUBST_INTERNALS)
|
|
771
|
+
});
|
|
772
|
+
const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains);
|
|
773
|
+
const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([
|
|
774
|
+
// eat recursive parens in sub expressions
|
|
775
|
+
{
|
|
776
|
+
begin: /\(/,
|
|
777
|
+
end: /\)/,
|
|
778
|
+
keywords: KEYWORDS$1$1,
|
|
779
|
+
contains: ["self"].concat(SUBST_AND_COMMENTS)
|
|
780
|
+
}
|
|
781
|
+
]);
|
|
782
|
+
const PARAMS = {
|
|
783
|
+
className: "params",
|
|
784
|
+
begin: /\(/,
|
|
785
|
+
end: /\)/,
|
|
786
|
+
excludeBegin: true,
|
|
787
|
+
excludeEnd: true,
|
|
788
|
+
keywords: KEYWORDS$1$1,
|
|
789
|
+
contains: PARAMS_CONTAINS
|
|
790
|
+
};
|
|
791
|
+
const CLASS_OR_EXTENDS = {
|
|
792
|
+
variants: [
|
|
793
|
+
// class Car extends vehicle
|
|
794
|
+
{
|
|
795
|
+
match: [
|
|
796
|
+
/class/,
|
|
797
|
+
/\s+/,
|
|
798
|
+
IDENT_RE$1$1,
|
|
799
|
+
/\s+/,
|
|
800
|
+
/extends/,
|
|
801
|
+
/\s+/,
|
|
802
|
+
regex.concat(IDENT_RE$1$1, "(", regex.concat(/\./, IDENT_RE$1$1), ")*")
|
|
803
|
+
],
|
|
804
|
+
scope: {
|
|
805
|
+
1: "keyword",
|
|
806
|
+
3: "title.class",
|
|
807
|
+
5: "keyword",
|
|
808
|
+
7: "title.class.inherited"
|
|
809
|
+
}
|
|
810
|
+
},
|
|
811
|
+
// class Car
|
|
812
|
+
{
|
|
813
|
+
match: [
|
|
814
|
+
/class/,
|
|
815
|
+
/\s+/,
|
|
816
|
+
IDENT_RE$1$1
|
|
817
|
+
],
|
|
818
|
+
scope: {
|
|
819
|
+
1: "keyword",
|
|
820
|
+
3: "title.class"
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
]
|
|
824
|
+
};
|
|
825
|
+
const CLASS_REFERENCE = {
|
|
826
|
+
relevance: 0,
|
|
827
|
+
match: regex.either(
|
|
828
|
+
// Hard coded exceptions
|
|
829
|
+
/\bJSON/,
|
|
830
|
+
// Float32Array, OutT
|
|
831
|
+
/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,
|
|
832
|
+
// CSSFactory, CSSFactoryT
|
|
833
|
+
/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,
|
|
834
|
+
// FPs, FPsT
|
|
835
|
+
/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/
|
|
836
|
+
// P
|
|
837
|
+
// single letters are not highlighted
|
|
838
|
+
// BLAH
|
|
839
|
+
// this will be flagged as a UPPER_CASE_CONSTANT instead
|
|
840
|
+
),
|
|
841
|
+
className: "title.class",
|
|
842
|
+
keywords: {
|
|
843
|
+
_: [
|
|
844
|
+
// se we still get relevance credit for JS library classes
|
|
845
|
+
...TYPES$1,
|
|
846
|
+
...ERROR_TYPES$1
|
|
847
|
+
]
|
|
848
|
+
}
|
|
849
|
+
};
|
|
850
|
+
const USE_STRICT = {
|
|
851
|
+
label: "use_strict",
|
|
852
|
+
className: "meta",
|
|
853
|
+
relevance: 10,
|
|
854
|
+
begin: /^\s*['"]use (strict|asm)['"]/
|
|
855
|
+
};
|
|
856
|
+
const FUNCTION_DEFINITION = {
|
|
857
|
+
variants: [
|
|
858
|
+
{
|
|
859
|
+
match: [
|
|
860
|
+
/function/,
|
|
861
|
+
/\s+/,
|
|
862
|
+
IDENT_RE$1$1,
|
|
863
|
+
/(?=\s*\()/
|
|
864
|
+
]
|
|
865
|
+
},
|
|
866
|
+
// anonymous function
|
|
867
|
+
{
|
|
868
|
+
match: [
|
|
869
|
+
/function/,
|
|
870
|
+
/\s*(?=\()/
|
|
871
|
+
]
|
|
872
|
+
}
|
|
873
|
+
],
|
|
874
|
+
className: {
|
|
875
|
+
1: "keyword",
|
|
876
|
+
3: "title.function"
|
|
877
|
+
},
|
|
878
|
+
label: "func.def",
|
|
879
|
+
contains: [PARAMS],
|
|
880
|
+
illegal: /%/
|
|
881
|
+
};
|
|
882
|
+
const UPPER_CASE_CONSTANT = {
|
|
883
|
+
relevance: 0,
|
|
884
|
+
match: /\b[A-Z][A-Z_0-9]+\b/,
|
|
885
|
+
className: "variable.constant"
|
|
886
|
+
};
|
|
887
|
+
function noneOf(list) {
|
|
888
|
+
return regex.concat("(?!", list.join("|"), ")");
|
|
889
|
+
}
|
|
890
|
+
const FUNCTION_CALL = {
|
|
891
|
+
match: regex.concat(
|
|
892
|
+
/\b/,
|
|
893
|
+
noneOf([
|
|
894
|
+
...BUILT_IN_GLOBALS$1,
|
|
895
|
+
"super",
|
|
896
|
+
"import"
|
|
897
|
+
]),
|
|
898
|
+
IDENT_RE$1$1,
|
|
899
|
+
regex.lookahead(/\(/)
|
|
900
|
+
),
|
|
901
|
+
className: "title.function",
|
|
902
|
+
relevance: 0
|
|
903
|
+
};
|
|
904
|
+
const PROPERTY_ACCESS = {
|
|
905
|
+
begin: regex.concat(/\./, regex.lookahead(
|
|
906
|
+
regex.concat(IDENT_RE$1$1, /(?![0-9A-Za-z$_(])/)
|
|
907
|
+
)),
|
|
908
|
+
end: IDENT_RE$1$1,
|
|
909
|
+
excludeBegin: true,
|
|
910
|
+
keywords: "prototype",
|
|
911
|
+
className: "property",
|
|
912
|
+
relevance: 0
|
|
913
|
+
};
|
|
914
|
+
const GETTER_OR_SETTER = {
|
|
915
|
+
match: [
|
|
916
|
+
/get|set/,
|
|
917
|
+
/\s+/,
|
|
918
|
+
IDENT_RE$1$1,
|
|
919
|
+
/(?=\()/
|
|
920
|
+
],
|
|
921
|
+
className: {
|
|
922
|
+
1: "keyword",
|
|
923
|
+
3: "title.function"
|
|
924
|
+
},
|
|
925
|
+
contains: [
|
|
926
|
+
{
|
|
927
|
+
// eat to avoid empty params
|
|
928
|
+
begin: /\(\)/
|
|
929
|
+
},
|
|
930
|
+
PARAMS
|
|
931
|
+
]
|
|
932
|
+
};
|
|
933
|
+
const FUNC_LEAD_IN_RE = "(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|" + hljs.UNDERSCORE_IDENT_RE + ")\\s*=>";
|
|
934
|
+
const FUNCTION_VARIABLE = {
|
|
935
|
+
match: [
|
|
936
|
+
/const|var|let/,
|
|
937
|
+
/\s+/,
|
|
938
|
+
IDENT_RE$1$1,
|
|
939
|
+
/\s*/,
|
|
940
|
+
/=\s*/,
|
|
941
|
+
/(async\s*)?/,
|
|
942
|
+
// async is optional
|
|
943
|
+
regex.lookahead(FUNC_LEAD_IN_RE)
|
|
944
|
+
],
|
|
945
|
+
keywords: "async",
|
|
946
|
+
className: {
|
|
947
|
+
1: "keyword",
|
|
948
|
+
3: "title.function"
|
|
949
|
+
},
|
|
950
|
+
contains: [
|
|
951
|
+
PARAMS
|
|
952
|
+
]
|
|
953
|
+
};
|
|
954
|
+
return {
|
|
955
|
+
name: "JavaScript",
|
|
956
|
+
aliases: ["js", "jsx", "mjs", "cjs"],
|
|
957
|
+
keywords: KEYWORDS$1$1,
|
|
958
|
+
// this will be extended by TypeScript
|
|
959
|
+
exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
|
|
960
|
+
illegal: /#(?![$_A-z])/,
|
|
961
|
+
contains: [
|
|
962
|
+
hljs.SHEBANG({
|
|
963
|
+
label: "shebang",
|
|
964
|
+
binary: "node",
|
|
965
|
+
relevance: 5
|
|
966
|
+
}),
|
|
967
|
+
USE_STRICT,
|
|
968
|
+
hljs.APOS_STRING_MODE,
|
|
969
|
+
hljs.QUOTE_STRING_MODE,
|
|
970
|
+
HTML_TEMPLATE,
|
|
971
|
+
CSS_TEMPLATE,
|
|
972
|
+
GRAPHQL_TEMPLATE,
|
|
973
|
+
TEMPLATE_STRING,
|
|
974
|
+
COMMENT,
|
|
975
|
+
// Skip numbers when they are part of a variable name
|
|
976
|
+
{ match: /\$\d+/ },
|
|
977
|
+
NUMBER,
|
|
978
|
+
CLASS_REFERENCE,
|
|
979
|
+
{
|
|
980
|
+
className: "attr",
|
|
981
|
+
begin: IDENT_RE$1$1 + regex.lookahead(":"),
|
|
982
|
+
relevance: 0
|
|
983
|
+
},
|
|
984
|
+
FUNCTION_VARIABLE,
|
|
985
|
+
{
|
|
986
|
+
// "value" container
|
|
987
|
+
begin: "(" + hljs.RE_STARTERS_RE + "|\\b(case|return|throw)\\b)\\s*",
|
|
988
|
+
keywords: "return throw case",
|
|
989
|
+
relevance: 0,
|
|
990
|
+
contains: [
|
|
991
|
+
COMMENT,
|
|
992
|
+
hljs.REGEXP_MODE,
|
|
993
|
+
{
|
|
994
|
+
className: "function",
|
|
995
|
+
// we have to count the parens to make sure we actually have the
|
|
996
|
+
// correct bounding ( ) before the =>. There could be any number of
|
|
997
|
+
// sub-expressions inside also surrounded by parens.
|
|
998
|
+
begin: FUNC_LEAD_IN_RE,
|
|
999
|
+
returnBegin: true,
|
|
1000
|
+
end: "\\s*=>",
|
|
1001
|
+
contains: [
|
|
1002
|
+
{
|
|
1003
|
+
className: "params",
|
|
1004
|
+
variants: [
|
|
1005
|
+
{
|
|
1006
|
+
begin: hljs.UNDERSCORE_IDENT_RE,
|
|
1007
|
+
relevance: 0
|
|
1008
|
+
},
|
|
1009
|
+
{
|
|
1010
|
+
className: null,
|
|
1011
|
+
begin: /\(\s*\)/,
|
|
1012
|
+
skip: true
|
|
1013
|
+
},
|
|
1014
|
+
{
|
|
1015
|
+
begin: /\(/,
|
|
1016
|
+
end: /\)/,
|
|
1017
|
+
excludeBegin: true,
|
|
1018
|
+
excludeEnd: true,
|
|
1019
|
+
keywords: KEYWORDS$1$1,
|
|
1020
|
+
contains: PARAMS_CONTAINS
|
|
1021
|
+
}
|
|
1022
|
+
]
|
|
1023
|
+
}
|
|
1024
|
+
]
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
// could be a comma delimited list of params to a function call
|
|
1028
|
+
begin: /,/,
|
|
1029
|
+
relevance: 0
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
match: /\s+/,
|
|
1033
|
+
relevance: 0
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
// JSX
|
|
1037
|
+
variants: [
|
|
1038
|
+
{ begin: FRAGMENT.begin, end: FRAGMENT.end },
|
|
1039
|
+
{ match: XML_SELF_CLOSING },
|
|
1040
|
+
{
|
|
1041
|
+
begin: XML_TAG.begin,
|
|
1042
|
+
// we carefully check the opening tag to see if it truly
|
|
1043
|
+
// is a tag and not a false positive
|
|
1044
|
+
"on:begin": XML_TAG.isTrulyOpeningTag,
|
|
1045
|
+
end: XML_TAG.end
|
|
1046
|
+
}
|
|
1047
|
+
],
|
|
1048
|
+
subLanguage: "xml",
|
|
1049
|
+
contains: [
|
|
1050
|
+
{
|
|
1051
|
+
begin: XML_TAG.begin,
|
|
1052
|
+
end: XML_TAG.end,
|
|
1053
|
+
skip: true,
|
|
1054
|
+
contains: ["self"]
|
|
1055
|
+
}
|
|
1056
|
+
]
|
|
1057
|
+
}
|
|
1058
|
+
]
|
|
1059
|
+
},
|
|
1060
|
+
FUNCTION_DEFINITION,
|
|
1061
|
+
{
|
|
1062
|
+
// prevent this from getting swallowed up by function
|
|
1063
|
+
// since they appear "function like"
|
|
1064
|
+
beginKeywords: "while if switch catch for"
|
|
1065
|
+
},
|
|
1066
|
+
{
|
|
1067
|
+
// we have to count the parens to make sure we actually have the correct
|
|
1068
|
+
// bounding ( ). There could be any number of sub-expressions inside
|
|
1069
|
+
// also surrounded by parens.
|
|
1070
|
+
begin: "\\b(?!function)" + hljs.UNDERSCORE_IDENT_RE + "\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",
|
|
1071
|
+
// end parens
|
|
1072
|
+
returnBegin: true,
|
|
1073
|
+
label: "func.def",
|
|
1074
|
+
contains: [
|
|
1075
|
+
PARAMS,
|
|
1076
|
+
hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$1$1, className: "title.function" })
|
|
1077
|
+
]
|
|
1078
|
+
},
|
|
1079
|
+
// catch ... so it won't trigger the property rule below
|
|
1080
|
+
{
|
|
1081
|
+
match: /\.\.\./,
|
|
1082
|
+
relevance: 0
|
|
1083
|
+
},
|
|
1084
|
+
PROPERTY_ACCESS,
|
|
1085
|
+
// hack: prevents detection of keywords in some circumstances
|
|
1086
|
+
// .keyword()
|
|
1087
|
+
// $keyword = x
|
|
1088
|
+
{
|
|
1089
|
+
match: "\\$" + IDENT_RE$1$1,
|
|
1090
|
+
relevance: 0
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
match: [/\bconstructor(?=\s*\()/],
|
|
1094
|
+
className: { 1: "title.function" },
|
|
1095
|
+
contains: [PARAMS]
|
|
1096
|
+
},
|
|
1097
|
+
FUNCTION_CALL,
|
|
1098
|
+
UPPER_CASE_CONSTANT,
|
|
1099
|
+
CLASS_OR_EXTENDS,
|
|
1100
|
+
GETTER_OR_SETTER,
|
|
1101
|
+
{
|
|
1102
|
+
match: /\$[(.]/
|
|
1103
|
+
// relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
|
|
1104
|
+
}
|
|
1105
|
+
]
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
function python(hljs) {
|
|
1109
|
+
const regex = hljs.regex;
|
|
1110
|
+
const IDENT_RE2 = new RegExp("[\\p{XID_Start}_]\\p{XID_Continue}*", "u");
|
|
1111
|
+
const RESERVED_WORDS = [
|
|
1112
|
+
"and",
|
|
1113
|
+
"as",
|
|
1114
|
+
"assert",
|
|
1115
|
+
"async",
|
|
1116
|
+
"await",
|
|
1117
|
+
"break",
|
|
1118
|
+
"case",
|
|
1119
|
+
"class",
|
|
1120
|
+
"continue",
|
|
1121
|
+
"def",
|
|
1122
|
+
"del",
|
|
1123
|
+
"elif",
|
|
1124
|
+
"else",
|
|
1125
|
+
"except",
|
|
1126
|
+
"finally",
|
|
1127
|
+
"for",
|
|
1128
|
+
"from",
|
|
1129
|
+
"global",
|
|
1130
|
+
"if",
|
|
1131
|
+
"import",
|
|
1132
|
+
"in",
|
|
1133
|
+
"is",
|
|
1134
|
+
"lambda",
|
|
1135
|
+
"match",
|
|
1136
|
+
"nonlocal|10",
|
|
1137
|
+
"not",
|
|
1138
|
+
"or",
|
|
1139
|
+
"pass",
|
|
1140
|
+
"raise",
|
|
1141
|
+
"return",
|
|
1142
|
+
"try",
|
|
1143
|
+
"while",
|
|
1144
|
+
"with",
|
|
1145
|
+
"yield"
|
|
1146
|
+
];
|
|
1147
|
+
const BUILT_INS2 = [
|
|
1148
|
+
"__import__",
|
|
1149
|
+
"abs",
|
|
1150
|
+
"all",
|
|
1151
|
+
"any",
|
|
1152
|
+
"ascii",
|
|
1153
|
+
"bin",
|
|
1154
|
+
"bool",
|
|
1155
|
+
"breakpoint",
|
|
1156
|
+
"bytearray",
|
|
1157
|
+
"bytes",
|
|
1158
|
+
"callable",
|
|
1159
|
+
"chr",
|
|
1160
|
+
"classmethod",
|
|
1161
|
+
"compile",
|
|
1162
|
+
"complex",
|
|
1163
|
+
"delattr",
|
|
1164
|
+
"dict",
|
|
1165
|
+
"dir",
|
|
1166
|
+
"divmod",
|
|
1167
|
+
"enumerate",
|
|
1168
|
+
"eval",
|
|
1169
|
+
"exec",
|
|
1170
|
+
"filter",
|
|
1171
|
+
"float",
|
|
1172
|
+
"format",
|
|
1173
|
+
"frozenset",
|
|
1174
|
+
"getattr",
|
|
1175
|
+
"globals",
|
|
1176
|
+
"hasattr",
|
|
1177
|
+
"hash",
|
|
1178
|
+
"help",
|
|
1179
|
+
"hex",
|
|
1180
|
+
"id",
|
|
1181
|
+
"input",
|
|
1182
|
+
"int",
|
|
1183
|
+
"isinstance",
|
|
1184
|
+
"issubclass",
|
|
1185
|
+
"iter",
|
|
1186
|
+
"len",
|
|
1187
|
+
"list",
|
|
1188
|
+
"locals",
|
|
1189
|
+
"map",
|
|
1190
|
+
"max",
|
|
1191
|
+
"memoryview",
|
|
1192
|
+
"min",
|
|
1193
|
+
"next",
|
|
1194
|
+
"object",
|
|
1195
|
+
"oct",
|
|
1196
|
+
"open",
|
|
1197
|
+
"ord",
|
|
1198
|
+
"pow",
|
|
1199
|
+
"print",
|
|
1200
|
+
"property",
|
|
1201
|
+
"range",
|
|
1202
|
+
"repr",
|
|
1203
|
+
"reversed",
|
|
1204
|
+
"round",
|
|
1205
|
+
"set",
|
|
1206
|
+
"setattr",
|
|
1207
|
+
"slice",
|
|
1208
|
+
"sorted",
|
|
1209
|
+
"staticmethod",
|
|
1210
|
+
"str",
|
|
1211
|
+
"sum",
|
|
1212
|
+
"super",
|
|
1213
|
+
"tuple",
|
|
1214
|
+
"type",
|
|
1215
|
+
"vars",
|
|
1216
|
+
"zip"
|
|
1217
|
+
];
|
|
1218
|
+
const LITERALS2 = [
|
|
1219
|
+
"__debug__",
|
|
1220
|
+
"Ellipsis",
|
|
1221
|
+
"False",
|
|
1222
|
+
"None",
|
|
1223
|
+
"NotImplemented",
|
|
1224
|
+
"True"
|
|
1225
|
+
];
|
|
1226
|
+
const TYPES2 = [
|
|
1227
|
+
"Any",
|
|
1228
|
+
"Callable",
|
|
1229
|
+
"Coroutine",
|
|
1230
|
+
"Dict",
|
|
1231
|
+
"List",
|
|
1232
|
+
"Literal",
|
|
1233
|
+
"Generic",
|
|
1234
|
+
"Optional",
|
|
1235
|
+
"Sequence",
|
|
1236
|
+
"Set",
|
|
1237
|
+
"Tuple",
|
|
1238
|
+
"Type",
|
|
1239
|
+
"Union"
|
|
1240
|
+
];
|
|
1241
|
+
const KEYWORDS2 = {
|
|
1242
|
+
$pattern: /[A-Za-z]\w+|__\w+__/,
|
|
1243
|
+
keyword: RESERVED_WORDS,
|
|
1244
|
+
built_in: BUILT_INS2,
|
|
1245
|
+
literal: LITERALS2,
|
|
1246
|
+
type: TYPES2
|
|
1247
|
+
};
|
|
1248
|
+
const PROMPT = {
|
|
1249
|
+
className: "meta",
|
|
1250
|
+
begin: /^(>>>|\.\.\.) /
|
|
1251
|
+
};
|
|
1252
|
+
const SUBST = {
|
|
1253
|
+
className: "subst",
|
|
1254
|
+
begin: /\{/,
|
|
1255
|
+
end: /\}/,
|
|
1256
|
+
keywords: KEYWORDS2,
|
|
1257
|
+
illegal: /#/
|
|
1258
|
+
};
|
|
1259
|
+
const LITERAL_BRACKET = {
|
|
1260
|
+
begin: /\{\{/,
|
|
1261
|
+
relevance: 0
|
|
1262
|
+
};
|
|
1263
|
+
const STRING = {
|
|
1264
|
+
className: "string",
|
|
1265
|
+
contains: [hljs.BACKSLASH_ESCAPE],
|
|
1266
|
+
variants: [
|
|
1267
|
+
{
|
|
1268
|
+
begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?'''/,
|
|
1269
|
+
end: /'''/,
|
|
1270
|
+
contains: [
|
|
1271
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1272
|
+
PROMPT
|
|
1273
|
+
],
|
|
1274
|
+
relevance: 10
|
|
1275
|
+
},
|
|
1276
|
+
{
|
|
1277
|
+
begin: /([uU]|[bB]|[rR]|[bB][rR]|[rR][bB])?"""/,
|
|
1278
|
+
end: /"""/,
|
|
1279
|
+
contains: [
|
|
1280
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1281
|
+
PROMPT
|
|
1282
|
+
],
|
|
1283
|
+
relevance: 10
|
|
1284
|
+
},
|
|
1285
|
+
{
|
|
1286
|
+
begin: /([fF][rR]|[rR][fF]|[fF])'''/,
|
|
1287
|
+
end: /'''/,
|
|
1288
|
+
contains: [
|
|
1289
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1290
|
+
PROMPT,
|
|
1291
|
+
LITERAL_BRACKET,
|
|
1292
|
+
SUBST
|
|
1293
|
+
]
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
begin: /([fF][rR]|[rR][fF]|[fF])"""/,
|
|
1297
|
+
end: /"""/,
|
|
1298
|
+
contains: [
|
|
1299
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1300
|
+
PROMPT,
|
|
1301
|
+
LITERAL_BRACKET,
|
|
1302
|
+
SUBST
|
|
1303
|
+
]
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
begin: /([uU]|[rR])'/,
|
|
1307
|
+
end: /'/,
|
|
1308
|
+
relevance: 10
|
|
1309
|
+
},
|
|
1310
|
+
{
|
|
1311
|
+
begin: /([uU]|[rR])"/,
|
|
1312
|
+
end: /"/,
|
|
1313
|
+
relevance: 10
|
|
1314
|
+
},
|
|
1315
|
+
{
|
|
1316
|
+
begin: /([bB]|[bB][rR]|[rR][bB])'/,
|
|
1317
|
+
end: /'/
|
|
1318
|
+
},
|
|
1319
|
+
{
|
|
1320
|
+
begin: /([bB]|[bB][rR]|[rR][bB])"/,
|
|
1321
|
+
end: /"/
|
|
1322
|
+
},
|
|
1323
|
+
{
|
|
1324
|
+
begin: /([fF][rR]|[rR][fF]|[fF])'/,
|
|
1325
|
+
end: /'/,
|
|
1326
|
+
contains: [
|
|
1327
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1328
|
+
LITERAL_BRACKET,
|
|
1329
|
+
SUBST
|
|
1330
|
+
]
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
begin: /([fF][rR]|[rR][fF]|[fF])"/,
|
|
1334
|
+
end: /"/,
|
|
1335
|
+
contains: [
|
|
1336
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1337
|
+
LITERAL_BRACKET,
|
|
1338
|
+
SUBST
|
|
1339
|
+
]
|
|
1340
|
+
},
|
|
1341
|
+
hljs.APOS_STRING_MODE,
|
|
1342
|
+
hljs.QUOTE_STRING_MODE
|
|
1343
|
+
]
|
|
1344
|
+
};
|
|
1345
|
+
const digitpart = "[0-9](_?[0-9])*";
|
|
1346
|
+
const pointfloat = `(\\b(${digitpart}))?\\.(${digitpart})|\\b(${digitpart})\\.`;
|
|
1347
|
+
const lookahead = `\\b|${RESERVED_WORDS.join("|")}`;
|
|
1348
|
+
const NUMBER = {
|
|
1349
|
+
className: "number",
|
|
1350
|
+
relevance: 0,
|
|
1351
|
+
variants: [
|
|
1352
|
+
// exponentfloat, pointfloat
|
|
1353
|
+
// https://docs.python.org/3.9/reference/lexical_analysis.html#floating-point-literals
|
|
1354
|
+
// optionally imaginary
|
|
1355
|
+
// https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
|
|
1356
|
+
// Note: no leading \b because floats can start with a decimal point
|
|
1357
|
+
// and we don't want to mishandle e.g. `fn(.5)`,
|
|
1358
|
+
// no trailing \b for pointfloat because it can end with a decimal point
|
|
1359
|
+
// and we don't want to mishandle e.g. `0..hex()`; this should be safe
|
|
1360
|
+
// because both MUST contain a decimal point and so cannot be confused with
|
|
1361
|
+
// the interior part of an identifier
|
|
1362
|
+
{
|
|
1363
|
+
begin: `(\\b(${digitpart})|(${pointfloat}))[eE][+-]?(${digitpart})[jJ]?(?=${lookahead})`
|
|
1364
|
+
},
|
|
1365
|
+
{
|
|
1366
|
+
begin: `(${pointfloat})[jJ]?`
|
|
1367
|
+
},
|
|
1368
|
+
// decinteger, bininteger, octinteger, hexinteger
|
|
1369
|
+
// https://docs.python.org/3.9/reference/lexical_analysis.html#integer-literals
|
|
1370
|
+
// optionally "long" in Python 2
|
|
1371
|
+
// https://docs.python.org/2.7/reference/lexical_analysis.html#integer-and-long-integer-literals
|
|
1372
|
+
// decinteger is optionally imaginary
|
|
1373
|
+
// https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
|
|
1374
|
+
{
|
|
1375
|
+
begin: `\\b([1-9](_?[0-9])*|0+(_?0)*)[lLjJ]?(?=${lookahead})`
|
|
1376
|
+
},
|
|
1377
|
+
{
|
|
1378
|
+
begin: `\\b0[bB](_?[01])+[lL]?(?=${lookahead})`
|
|
1379
|
+
},
|
|
1380
|
+
{
|
|
1381
|
+
begin: `\\b0[oO](_?[0-7])+[lL]?(?=${lookahead})`
|
|
1382
|
+
},
|
|
1383
|
+
{
|
|
1384
|
+
begin: `\\b0[xX](_?[0-9a-fA-F])+[lL]?(?=${lookahead})`
|
|
1385
|
+
},
|
|
1386
|
+
// imagnumber (digitpart-based)
|
|
1387
|
+
// https://docs.python.org/3.9/reference/lexical_analysis.html#imaginary-literals
|
|
1388
|
+
{
|
|
1389
|
+
begin: `\\b(${digitpart})[jJ](?=${lookahead})`
|
|
1390
|
+
}
|
|
1391
|
+
]
|
|
1392
|
+
};
|
|
1393
|
+
const COMMENT_TYPE = {
|
|
1394
|
+
className: "comment",
|
|
1395
|
+
begin: regex.lookahead(/# type:/),
|
|
1396
|
+
end: /$/,
|
|
1397
|
+
keywords: KEYWORDS2,
|
|
1398
|
+
contains: [
|
|
1399
|
+
{
|
|
1400
|
+
// prevent keywords from coloring `type`
|
|
1401
|
+
begin: /# type:/
|
|
1402
|
+
},
|
|
1403
|
+
// comment within a datatype comment includes no keywords
|
|
1404
|
+
{
|
|
1405
|
+
begin: /#/,
|
|
1406
|
+
end: /\b\B/,
|
|
1407
|
+
endsWithParent: true
|
|
1408
|
+
}
|
|
1409
|
+
]
|
|
1410
|
+
};
|
|
1411
|
+
const PARAMS = {
|
|
1412
|
+
className: "params",
|
|
1413
|
+
variants: [
|
|
1414
|
+
// Exclude params in functions without params
|
|
1415
|
+
{
|
|
1416
|
+
className: "",
|
|
1417
|
+
begin: /\(\s*\)/,
|
|
1418
|
+
skip: true
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
begin: /\(/,
|
|
1422
|
+
end: /\)/,
|
|
1423
|
+
excludeBegin: true,
|
|
1424
|
+
excludeEnd: true,
|
|
1425
|
+
keywords: KEYWORDS2,
|
|
1426
|
+
contains: [
|
|
1427
|
+
"self",
|
|
1428
|
+
PROMPT,
|
|
1429
|
+
NUMBER,
|
|
1430
|
+
STRING,
|
|
1431
|
+
hljs.HASH_COMMENT_MODE
|
|
1432
|
+
]
|
|
1433
|
+
}
|
|
1434
|
+
]
|
|
1435
|
+
};
|
|
1436
|
+
SUBST.contains = [
|
|
1437
|
+
STRING,
|
|
1438
|
+
NUMBER,
|
|
1439
|
+
PROMPT
|
|
1440
|
+
];
|
|
1441
|
+
return {
|
|
1442
|
+
name: "Python",
|
|
1443
|
+
aliases: [
|
|
1444
|
+
"py",
|
|
1445
|
+
"gyp",
|
|
1446
|
+
"ipython"
|
|
1447
|
+
],
|
|
1448
|
+
unicodeRegex: true,
|
|
1449
|
+
keywords: KEYWORDS2,
|
|
1450
|
+
illegal: /(<\/|\?)|=>/,
|
|
1451
|
+
contains: [
|
|
1452
|
+
PROMPT,
|
|
1453
|
+
NUMBER,
|
|
1454
|
+
{
|
|
1455
|
+
// very common convention
|
|
1456
|
+
begin: /\bself\b/
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
// eat "if" prior to string so that it won't accidentally be
|
|
1460
|
+
// labeled as an f-string
|
|
1461
|
+
beginKeywords: "if",
|
|
1462
|
+
relevance: 0
|
|
1463
|
+
},
|
|
1464
|
+
STRING,
|
|
1465
|
+
COMMENT_TYPE,
|
|
1466
|
+
hljs.HASH_COMMENT_MODE,
|
|
1467
|
+
{
|
|
1468
|
+
match: [
|
|
1469
|
+
/\bdef/,
|
|
1470
|
+
/\s+/,
|
|
1471
|
+
IDENT_RE2
|
|
1472
|
+
],
|
|
1473
|
+
scope: {
|
|
1474
|
+
1: "keyword",
|
|
1475
|
+
3: "title.function"
|
|
1476
|
+
},
|
|
1477
|
+
contains: [PARAMS]
|
|
1478
|
+
},
|
|
1479
|
+
{
|
|
1480
|
+
variants: [
|
|
1481
|
+
{
|
|
1482
|
+
match: [
|
|
1483
|
+
/\bclass/,
|
|
1484
|
+
/\s+/,
|
|
1485
|
+
IDENT_RE2,
|
|
1486
|
+
/\s*/,
|
|
1487
|
+
/\(\s*/,
|
|
1488
|
+
IDENT_RE2,
|
|
1489
|
+
/\s*\)/
|
|
1490
|
+
]
|
|
1491
|
+
},
|
|
1492
|
+
{
|
|
1493
|
+
match: [
|
|
1494
|
+
/\bclass/,
|
|
1495
|
+
/\s+/,
|
|
1496
|
+
IDENT_RE2
|
|
1497
|
+
]
|
|
1498
|
+
}
|
|
1499
|
+
],
|
|
1500
|
+
scope: {
|
|
1501
|
+
1: "keyword",
|
|
1502
|
+
3: "title.class",
|
|
1503
|
+
6: "title.class.inherited"
|
|
1504
|
+
}
|
|
1505
|
+
},
|
|
1506
|
+
{
|
|
1507
|
+
className: "meta",
|
|
1508
|
+
begin: /^[\t ]*@/,
|
|
1509
|
+
end: /(?=#)|$/,
|
|
1510
|
+
contains: [
|
|
1511
|
+
NUMBER,
|
|
1512
|
+
PARAMS,
|
|
1513
|
+
STRING
|
|
1514
|
+
]
|
|
1515
|
+
}
|
|
1516
|
+
]
|
|
1517
|
+
};
|
|
1518
|
+
}
|
|
1519
|
+
const IDENT_RE = "[A-Za-z$_][0-9A-Za-z$_]*";
|
|
1520
|
+
const KEYWORDS = [
|
|
1521
|
+
"as",
|
|
1522
|
+
// for exports
|
|
1523
|
+
"in",
|
|
1524
|
+
"of",
|
|
1525
|
+
"if",
|
|
1526
|
+
"for",
|
|
1527
|
+
"while",
|
|
1528
|
+
"finally",
|
|
1529
|
+
"var",
|
|
1530
|
+
"new",
|
|
1531
|
+
"function",
|
|
1532
|
+
"do",
|
|
1533
|
+
"return",
|
|
1534
|
+
"void",
|
|
1535
|
+
"else",
|
|
1536
|
+
"break",
|
|
1537
|
+
"catch",
|
|
1538
|
+
"instanceof",
|
|
1539
|
+
"with",
|
|
1540
|
+
"throw",
|
|
1541
|
+
"case",
|
|
1542
|
+
"default",
|
|
1543
|
+
"try",
|
|
1544
|
+
"switch",
|
|
1545
|
+
"continue",
|
|
1546
|
+
"typeof",
|
|
1547
|
+
"delete",
|
|
1548
|
+
"let",
|
|
1549
|
+
"yield",
|
|
1550
|
+
"const",
|
|
1551
|
+
"class",
|
|
1552
|
+
// JS handles these with a special rule
|
|
1553
|
+
// "get",
|
|
1554
|
+
// "set",
|
|
1555
|
+
"debugger",
|
|
1556
|
+
"async",
|
|
1557
|
+
"await",
|
|
1558
|
+
"static",
|
|
1559
|
+
"import",
|
|
1560
|
+
"from",
|
|
1561
|
+
"export",
|
|
1562
|
+
"extends"
|
|
1563
|
+
];
|
|
1564
|
+
const LITERALS = [
|
|
1565
|
+
"true",
|
|
1566
|
+
"false",
|
|
1567
|
+
"null",
|
|
1568
|
+
"undefined",
|
|
1569
|
+
"NaN",
|
|
1570
|
+
"Infinity"
|
|
1571
|
+
];
|
|
1572
|
+
const TYPES = [
|
|
1573
|
+
// Fundamental objects
|
|
1574
|
+
"Object",
|
|
1575
|
+
"Function",
|
|
1576
|
+
"Boolean",
|
|
1577
|
+
"Symbol",
|
|
1578
|
+
// numbers and dates
|
|
1579
|
+
"Math",
|
|
1580
|
+
"Date",
|
|
1581
|
+
"Number",
|
|
1582
|
+
"BigInt",
|
|
1583
|
+
// text
|
|
1584
|
+
"String",
|
|
1585
|
+
"RegExp",
|
|
1586
|
+
// Indexed collections
|
|
1587
|
+
"Array",
|
|
1588
|
+
"Float32Array",
|
|
1589
|
+
"Float64Array",
|
|
1590
|
+
"Int8Array",
|
|
1591
|
+
"Uint8Array",
|
|
1592
|
+
"Uint8ClampedArray",
|
|
1593
|
+
"Int16Array",
|
|
1594
|
+
"Int32Array",
|
|
1595
|
+
"Uint16Array",
|
|
1596
|
+
"Uint32Array",
|
|
1597
|
+
"BigInt64Array",
|
|
1598
|
+
"BigUint64Array",
|
|
1599
|
+
// Keyed collections
|
|
1600
|
+
"Set",
|
|
1601
|
+
"Map",
|
|
1602
|
+
"WeakSet",
|
|
1603
|
+
"WeakMap",
|
|
1604
|
+
// Structured data
|
|
1605
|
+
"ArrayBuffer",
|
|
1606
|
+
"SharedArrayBuffer",
|
|
1607
|
+
"Atomics",
|
|
1608
|
+
"DataView",
|
|
1609
|
+
"JSON",
|
|
1610
|
+
// Control abstraction objects
|
|
1611
|
+
"Promise",
|
|
1612
|
+
"Generator",
|
|
1613
|
+
"GeneratorFunction",
|
|
1614
|
+
"AsyncFunction",
|
|
1615
|
+
// Reflection
|
|
1616
|
+
"Reflect",
|
|
1617
|
+
"Proxy",
|
|
1618
|
+
// Internationalization
|
|
1619
|
+
"Intl",
|
|
1620
|
+
// WebAssembly
|
|
1621
|
+
"WebAssembly"
|
|
1622
|
+
];
|
|
1623
|
+
const ERROR_TYPES = [
|
|
1624
|
+
"Error",
|
|
1625
|
+
"EvalError",
|
|
1626
|
+
"InternalError",
|
|
1627
|
+
"RangeError",
|
|
1628
|
+
"ReferenceError",
|
|
1629
|
+
"SyntaxError",
|
|
1630
|
+
"TypeError",
|
|
1631
|
+
"URIError"
|
|
1632
|
+
];
|
|
1633
|
+
const BUILT_IN_GLOBALS = [
|
|
1634
|
+
"setInterval",
|
|
1635
|
+
"setTimeout",
|
|
1636
|
+
"clearInterval",
|
|
1637
|
+
"clearTimeout",
|
|
1638
|
+
"require",
|
|
1639
|
+
"exports",
|
|
1640
|
+
"eval",
|
|
1641
|
+
"isFinite",
|
|
1642
|
+
"isNaN",
|
|
1643
|
+
"parseFloat",
|
|
1644
|
+
"parseInt",
|
|
1645
|
+
"decodeURI",
|
|
1646
|
+
"decodeURIComponent",
|
|
1647
|
+
"encodeURI",
|
|
1648
|
+
"encodeURIComponent",
|
|
1649
|
+
"escape",
|
|
1650
|
+
"unescape"
|
|
1651
|
+
];
|
|
1652
|
+
const BUILT_IN_VARIABLES = [
|
|
1653
|
+
"arguments",
|
|
1654
|
+
"this",
|
|
1655
|
+
"super",
|
|
1656
|
+
"console",
|
|
1657
|
+
"window",
|
|
1658
|
+
"document",
|
|
1659
|
+
"localStorage",
|
|
1660
|
+
"sessionStorage",
|
|
1661
|
+
"module",
|
|
1662
|
+
"global"
|
|
1663
|
+
// Node.js
|
|
1664
|
+
];
|
|
1665
|
+
const BUILT_INS = [].concat(
|
|
1666
|
+
BUILT_IN_GLOBALS,
|
|
1667
|
+
TYPES,
|
|
1668
|
+
ERROR_TYPES
|
|
1669
|
+
);
|
|
1670
|
+
function javascript(hljs) {
|
|
1671
|
+
const regex = hljs.regex;
|
|
1672
|
+
const hasClosingTag = (match, { after }) => {
|
|
1673
|
+
const tag = "</" + match[0].slice(1);
|
|
1674
|
+
const pos = match.input.indexOf(tag, after);
|
|
1675
|
+
return pos !== -1;
|
|
1676
|
+
};
|
|
1677
|
+
const IDENT_RE$12 = IDENT_RE;
|
|
1678
|
+
const FRAGMENT = {
|
|
1679
|
+
begin: "<>",
|
|
1680
|
+
end: "</>"
|
|
1681
|
+
};
|
|
1682
|
+
const XML_SELF_CLOSING = /<[A-Za-z0-9\\._:-]+\s*\/>/;
|
|
1683
|
+
const XML_TAG = {
|
|
1684
|
+
begin: /<[A-Za-z0-9\\._:-]+/,
|
|
1685
|
+
end: /\/[A-Za-z0-9\\._:-]+>|\/>/,
|
|
1686
|
+
/**
|
|
1687
|
+
* @param {RegExpMatchArray} match
|
|
1688
|
+
* @param {CallbackResponse} response
|
|
1689
|
+
*/
|
|
1690
|
+
isTrulyOpeningTag: (match, response) => {
|
|
1691
|
+
const afterMatchIndex = match[0].length + match.index;
|
|
1692
|
+
const nextChar = match.input[afterMatchIndex];
|
|
1693
|
+
if (
|
|
1694
|
+
// HTML should not include another raw `<` inside a tag
|
|
1695
|
+
// nested type?
|
|
1696
|
+
// `<Array<Array<number>>`, etc.
|
|
1697
|
+
nextChar === "<" || // the , gives away that this is not HTML
|
|
1698
|
+
// `<T, A extends keyof T, V>`
|
|
1699
|
+
nextChar === ","
|
|
1700
|
+
) {
|
|
1701
|
+
response.ignoreMatch();
|
|
1702
|
+
return;
|
|
1703
|
+
}
|
|
1704
|
+
if (nextChar === ">") {
|
|
1705
|
+
if (!hasClosingTag(match, { after: afterMatchIndex })) {
|
|
1706
|
+
response.ignoreMatch();
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
let m;
|
|
1710
|
+
const afterMatch = match.input.substring(afterMatchIndex);
|
|
1711
|
+
if (m = afterMatch.match(/^\s*=/)) {
|
|
1712
|
+
response.ignoreMatch();
|
|
1713
|
+
return;
|
|
1714
|
+
}
|
|
1715
|
+
if (m = afterMatch.match(/^\s+extends\s+/)) {
|
|
1716
|
+
if (m.index === 0) {
|
|
1717
|
+
response.ignoreMatch();
|
|
1718
|
+
return;
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
};
|
|
1723
|
+
const KEYWORDS$12 = {
|
|
1724
|
+
$pattern: IDENT_RE,
|
|
1725
|
+
keyword: KEYWORDS,
|
|
1726
|
+
literal: LITERALS,
|
|
1727
|
+
built_in: BUILT_INS,
|
|
1728
|
+
"variable.language": BUILT_IN_VARIABLES
|
|
1729
|
+
};
|
|
1730
|
+
const decimalDigits = "[0-9](_?[0-9])*";
|
|
1731
|
+
const frac = `\\.(${decimalDigits})`;
|
|
1732
|
+
const decimalInteger = `0|[1-9](_?[0-9])*|0[0-7]*[89][0-9]*`;
|
|
1733
|
+
const NUMBER = {
|
|
1734
|
+
className: "number",
|
|
1735
|
+
variants: [
|
|
1736
|
+
// DecimalLiteral
|
|
1737
|
+
{ begin: `(\\b(${decimalInteger})((${frac})|\\.)?|(${frac}))[eE][+-]?(${decimalDigits})\\b` },
|
|
1738
|
+
{ begin: `\\b(${decimalInteger})\\b((${frac})\\b|\\.)?|(${frac})\\b` },
|
|
1739
|
+
// DecimalBigIntegerLiteral
|
|
1740
|
+
{ begin: `\\b(0|[1-9](_?[0-9])*)n\\b` },
|
|
1741
|
+
// NonDecimalIntegerLiteral
|
|
1742
|
+
{ begin: "\\b0[xX][0-9a-fA-F](_?[0-9a-fA-F])*n?\\b" },
|
|
1743
|
+
{ begin: "\\b0[bB][0-1](_?[0-1])*n?\\b" },
|
|
1744
|
+
{ begin: "\\b0[oO][0-7](_?[0-7])*n?\\b" },
|
|
1745
|
+
// LegacyOctalIntegerLiteral (does not include underscore separators)
|
|
1746
|
+
// https://tc39.es/ecma262/#sec-additional-syntax-numeric-literals
|
|
1747
|
+
{ begin: "\\b0[0-7]+n?\\b" }
|
|
1748
|
+
],
|
|
1749
|
+
relevance: 0
|
|
1750
|
+
};
|
|
1751
|
+
const SUBST = {
|
|
1752
|
+
className: "subst",
|
|
1753
|
+
begin: "\\$\\{",
|
|
1754
|
+
end: "\\}",
|
|
1755
|
+
keywords: KEYWORDS$12,
|
|
1756
|
+
contains: []
|
|
1757
|
+
// defined later
|
|
1758
|
+
};
|
|
1759
|
+
const HTML_TEMPLATE = {
|
|
1760
|
+
begin: "html`",
|
|
1761
|
+
end: "",
|
|
1762
|
+
starts: {
|
|
1763
|
+
end: "`",
|
|
1764
|
+
returnEnd: false,
|
|
1765
|
+
contains: [
|
|
1766
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1767
|
+
SUBST
|
|
1768
|
+
],
|
|
1769
|
+
subLanguage: "xml"
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1772
|
+
const CSS_TEMPLATE = {
|
|
1773
|
+
begin: "css`",
|
|
1774
|
+
end: "",
|
|
1775
|
+
starts: {
|
|
1776
|
+
end: "`",
|
|
1777
|
+
returnEnd: false,
|
|
1778
|
+
contains: [
|
|
1779
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1780
|
+
SUBST
|
|
1781
|
+
],
|
|
1782
|
+
subLanguage: "css"
|
|
1783
|
+
}
|
|
1784
|
+
};
|
|
1785
|
+
const GRAPHQL_TEMPLATE = {
|
|
1786
|
+
begin: "gql`",
|
|
1787
|
+
end: "",
|
|
1788
|
+
starts: {
|
|
1789
|
+
end: "`",
|
|
1790
|
+
returnEnd: false,
|
|
1791
|
+
contains: [
|
|
1792
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1793
|
+
SUBST
|
|
1794
|
+
],
|
|
1795
|
+
subLanguage: "graphql"
|
|
1796
|
+
}
|
|
1797
|
+
};
|
|
1798
|
+
const TEMPLATE_STRING = {
|
|
1799
|
+
className: "string",
|
|
1800
|
+
begin: "`",
|
|
1801
|
+
end: "`",
|
|
1802
|
+
contains: [
|
|
1803
|
+
hljs.BACKSLASH_ESCAPE,
|
|
1804
|
+
SUBST
|
|
1805
|
+
]
|
|
1806
|
+
};
|
|
1807
|
+
const JSDOC_COMMENT = hljs.COMMENT(
|
|
1808
|
+
/\/\*\*(?!\/)/,
|
|
1809
|
+
"\\*/",
|
|
1810
|
+
{
|
|
1811
|
+
relevance: 0,
|
|
1812
|
+
contains: [
|
|
1813
|
+
{
|
|
1814
|
+
begin: "(?=@[A-Za-z]+)",
|
|
1815
|
+
relevance: 0,
|
|
1816
|
+
contains: [
|
|
1817
|
+
{
|
|
1818
|
+
className: "doctag",
|
|
1819
|
+
begin: "@[A-Za-z]+"
|
|
1820
|
+
},
|
|
1821
|
+
{
|
|
1822
|
+
className: "type",
|
|
1823
|
+
begin: "\\{",
|
|
1824
|
+
end: "\\}",
|
|
1825
|
+
excludeEnd: true,
|
|
1826
|
+
excludeBegin: true,
|
|
1827
|
+
relevance: 0
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
className: "variable",
|
|
1831
|
+
begin: IDENT_RE$12 + "(?=\\s*(-)|$)",
|
|
1832
|
+
endsParent: true,
|
|
1833
|
+
relevance: 0
|
|
1834
|
+
},
|
|
1835
|
+
// eat spaces (not newlines) so we can find
|
|
1836
|
+
// types or variables
|
|
1837
|
+
{
|
|
1838
|
+
begin: /(?=[^\n])\s/,
|
|
1839
|
+
relevance: 0
|
|
1840
|
+
}
|
|
1841
|
+
]
|
|
1842
|
+
}
|
|
1843
|
+
]
|
|
1844
|
+
}
|
|
1845
|
+
);
|
|
1846
|
+
const COMMENT = {
|
|
1847
|
+
className: "comment",
|
|
1848
|
+
variants: [
|
|
1849
|
+
JSDOC_COMMENT,
|
|
1850
|
+
hljs.C_BLOCK_COMMENT_MODE,
|
|
1851
|
+
hljs.C_LINE_COMMENT_MODE
|
|
1852
|
+
]
|
|
1853
|
+
};
|
|
1854
|
+
const SUBST_INTERNALS = [
|
|
1855
|
+
hljs.APOS_STRING_MODE,
|
|
1856
|
+
hljs.QUOTE_STRING_MODE,
|
|
1857
|
+
HTML_TEMPLATE,
|
|
1858
|
+
CSS_TEMPLATE,
|
|
1859
|
+
GRAPHQL_TEMPLATE,
|
|
1860
|
+
TEMPLATE_STRING,
|
|
1861
|
+
// Skip numbers when they are part of a variable name
|
|
1862
|
+
{ match: /\$\d+/ },
|
|
1863
|
+
NUMBER
|
|
1864
|
+
// This is intentional:
|
|
1865
|
+
// See https://github.com/highlightjs/highlight.js/issues/3288
|
|
1866
|
+
// hljs.REGEXP_MODE
|
|
1867
|
+
];
|
|
1868
|
+
SUBST.contains = SUBST_INTERNALS.concat({
|
|
1869
|
+
// we need to pair up {} inside our subst to prevent
|
|
1870
|
+
// it from ending too early by matching another }
|
|
1871
|
+
begin: /\{/,
|
|
1872
|
+
end: /\}/,
|
|
1873
|
+
keywords: KEYWORDS$12,
|
|
1874
|
+
contains: [
|
|
1875
|
+
"self"
|
|
1876
|
+
].concat(SUBST_INTERNALS)
|
|
1877
|
+
});
|
|
1878
|
+
const SUBST_AND_COMMENTS = [].concat(COMMENT, SUBST.contains);
|
|
1879
|
+
const PARAMS_CONTAINS = SUBST_AND_COMMENTS.concat([
|
|
1880
|
+
// eat recursive parens in sub expressions
|
|
1881
|
+
{
|
|
1882
|
+
begin: /\(/,
|
|
1883
|
+
end: /\)/,
|
|
1884
|
+
keywords: KEYWORDS$12,
|
|
1885
|
+
contains: ["self"].concat(SUBST_AND_COMMENTS)
|
|
1886
|
+
}
|
|
1887
|
+
]);
|
|
1888
|
+
const PARAMS = {
|
|
1889
|
+
className: "params",
|
|
1890
|
+
begin: /\(/,
|
|
1891
|
+
end: /\)/,
|
|
1892
|
+
excludeBegin: true,
|
|
1893
|
+
excludeEnd: true,
|
|
1894
|
+
keywords: KEYWORDS$12,
|
|
1895
|
+
contains: PARAMS_CONTAINS
|
|
1896
|
+
};
|
|
1897
|
+
const CLASS_OR_EXTENDS = {
|
|
1898
|
+
variants: [
|
|
1899
|
+
// class Car extends vehicle
|
|
1900
|
+
{
|
|
1901
|
+
match: [
|
|
1902
|
+
/class/,
|
|
1903
|
+
/\s+/,
|
|
1904
|
+
IDENT_RE$12,
|
|
1905
|
+
/\s+/,
|
|
1906
|
+
/extends/,
|
|
1907
|
+
/\s+/,
|
|
1908
|
+
regex.concat(IDENT_RE$12, "(", regex.concat(/\./, IDENT_RE$12), ")*")
|
|
1909
|
+
],
|
|
1910
|
+
scope: {
|
|
1911
|
+
1: "keyword",
|
|
1912
|
+
3: "title.class",
|
|
1913
|
+
5: "keyword",
|
|
1914
|
+
7: "title.class.inherited"
|
|
1915
|
+
}
|
|
1916
|
+
},
|
|
1917
|
+
// class Car
|
|
1918
|
+
{
|
|
1919
|
+
match: [
|
|
1920
|
+
/class/,
|
|
1921
|
+
/\s+/,
|
|
1922
|
+
IDENT_RE$12
|
|
1923
|
+
],
|
|
1924
|
+
scope: {
|
|
1925
|
+
1: "keyword",
|
|
1926
|
+
3: "title.class"
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
]
|
|
1930
|
+
};
|
|
1931
|
+
const CLASS_REFERENCE = {
|
|
1932
|
+
relevance: 0,
|
|
1933
|
+
match: regex.either(
|
|
1934
|
+
// Hard coded exceptions
|
|
1935
|
+
/\bJSON/,
|
|
1936
|
+
// Float32Array, OutT
|
|
1937
|
+
/\b[A-Z][a-z]+([A-Z][a-z]*|\d)*/,
|
|
1938
|
+
// CSSFactory, CSSFactoryT
|
|
1939
|
+
/\b[A-Z]{2,}([A-Z][a-z]+|\d)+([A-Z][a-z]*)*/,
|
|
1940
|
+
// FPs, FPsT
|
|
1941
|
+
/\b[A-Z]{2,}[a-z]+([A-Z][a-z]+|\d)*([A-Z][a-z]*)*/
|
|
1942
|
+
// P
|
|
1943
|
+
// single letters are not highlighted
|
|
1944
|
+
// BLAH
|
|
1945
|
+
// this will be flagged as a UPPER_CASE_CONSTANT instead
|
|
1946
|
+
),
|
|
1947
|
+
className: "title.class",
|
|
1948
|
+
keywords: {
|
|
1949
|
+
_: [
|
|
1950
|
+
// se we still get relevance credit for JS library classes
|
|
1951
|
+
...TYPES,
|
|
1952
|
+
...ERROR_TYPES
|
|
1953
|
+
]
|
|
1954
|
+
}
|
|
1955
|
+
};
|
|
1956
|
+
const USE_STRICT = {
|
|
1957
|
+
label: "use_strict",
|
|
1958
|
+
className: "meta",
|
|
1959
|
+
relevance: 10,
|
|
1960
|
+
begin: /^\s*['"]use (strict|asm)['"]/
|
|
1961
|
+
};
|
|
1962
|
+
const FUNCTION_DEFINITION = {
|
|
1963
|
+
variants: [
|
|
1964
|
+
{
|
|
1965
|
+
match: [
|
|
1966
|
+
/function/,
|
|
1967
|
+
/\s+/,
|
|
1968
|
+
IDENT_RE$12,
|
|
1969
|
+
/(?=\s*\()/
|
|
1970
|
+
]
|
|
1971
|
+
},
|
|
1972
|
+
// anonymous function
|
|
1973
|
+
{
|
|
1974
|
+
match: [
|
|
1975
|
+
/function/,
|
|
1976
|
+
/\s*(?=\()/
|
|
1977
|
+
]
|
|
1978
|
+
}
|
|
1979
|
+
],
|
|
1980
|
+
className: {
|
|
1981
|
+
1: "keyword",
|
|
1982
|
+
3: "title.function"
|
|
1983
|
+
},
|
|
1984
|
+
label: "func.def",
|
|
1985
|
+
contains: [PARAMS],
|
|
1986
|
+
illegal: /%/
|
|
1987
|
+
};
|
|
1988
|
+
const UPPER_CASE_CONSTANT = {
|
|
1989
|
+
relevance: 0,
|
|
1990
|
+
match: /\b[A-Z][A-Z_0-9]+\b/,
|
|
1991
|
+
className: "variable.constant"
|
|
1992
|
+
};
|
|
1993
|
+
function noneOf(list) {
|
|
1994
|
+
return regex.concat("(?!", list.join("|"), ")");
|
|
1995
|
+
}
|
|
1996
|
+
const FUNCTION_CALL = {
|
|
1997
|
+
match: regex.concat(
|
|
1998
|
+
/\b/,
|
|
1999
|
+
noneOf([
|
|
2000
|
+
...BUILT_IN_GLOBALS,
|
|
2001
|
+
"super",
|
|
2002
|
+
"import"
|
|
2003
|
+
]),
|
|
2004
|
+
IDENT_RE$12,
|
|
2005
|
+
regex.lookahead(/\(/)
|
|
2006
|
+
),
|
|
2007
|
+
className: "title.function",
|
|
2008
|
+
relevance: 0
|
|
2009
|
+
};
|
|
2010
|
+
const PROPERTY_ACCESS = {
|
|
2011
|
+
begin: regex.concat(/\./, regex.lookahead(
|
|
2012
|
+
regex.concat(IDENT_RE$12, /(?![0-9A-Za-z$_(])/)
|
|
2013
|
+
)),
|
|
2014
|
+
end: IDENT_RE$12,
|
|
2015
|
+
excludeBegin: true,
|
|
2016
|
+
keywords: "prototype",
|
|
2017
|
+
className: "property",
|
|
2018
|
+
relevance: 0
|
|
2019
|
+
};
|
|
2020
|
+
const GETTER_OR_SETTER = {
|
|
2021
|
+
match: [
|
|
2022
|
+
/get|set/,
|
|
2023
|
+
/\s+/,
|
|
2024
|
+
IDENT_RE$12,
|
|
2025
|
+
/(?=\()/
|
|
2026
|
+
],
|
|
2027
|
+
className: {
|
|
2028
|
+
1: "keyword",
|
|
2029
|
+
3: "title.function"
|
|
2030
|
+
},
|
|
2031
|
+
contains: [
|
|
2032
|
+
{
|
|
2033
|
+
// eat to avoid empty params
|
|
2034
|
+
begin: /\(\)/
|
|
2035
|
+
},
|
|
2036
|
+
PARAMS
|
|
2037
|
+
]
|
|
2038
|
+
};
|
|
2039
|
+
const FUNC_LEAD_IN_RE = "(\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)|" + hljs.UNDERSCORE_IDENT_RE + ")\\s*=>";
|
|
2040
|
+
const FUNCTION_VARIABLE = {
|
|
2041
|
+
match: [
|
|
2042
|
+
/const|var|let/,
|
|
2043
|
+
/\s+/,
|
|
2044
|
+
IDENT_RE$12,
|
|
2045
|
+
/\s*/,
|
|
2046
|
+
/=\s*/,
|
|
2047
|
+
/(async\s*)?/,
|
|
2048
|
+
// async is optional
|
|
2049
|
+
regex.lookahead(FUNC_LEAD_IN_RE)
|
|
2050
|
+
],
|
|
2051
|
+
keywords: "async",
|
|
2052
|
+
className: {
|
|
2053
|
+
1: "keyword",
|
|
2054
|
+
3: "title.function"
|
|
2055
|
+
},
|
|
2056
|
+
contains: [
|
|
2057
|
+
PARAMS
|
|
2058
|
+
]
|
|
2059
|
+
};
|
|
2060
|
+
return {
|
|
2061
|
+
name: "JavaScript",
|
|
2062
|
+
aliases: ["js", "jsx", "mjs", "cjs"],
|
|
2063
|
+
keywords: KEYWORDS$12,
|
|
2064
|
+
// this will be extended by TypeScript
|
|
2065
|
+
exports: { PARAMS_CONTAINS, CLASS_REFERENCE },
|
|
2066
|
+
illegal: /#(?![$_A-z])/,
|
|
2067
|
+
contains: [
|
|
2068
|
+
hljs.SHEBANG({
|
|
2069
|
+
label: "shebang",
|
|
2070
|
+
binary: "node",
|
|
2071
|
+
relevance: 5
|
|
2072
|
+
}),
|
|
2073
|
+
USE_STRICT,
|
|
2074
|
+
hljs.APOS_STRING_MODE,
|
|
2075
|
+
hljs.QUOTE_STRING_MODE,
|
|
2076
|
+
HTML_TEMPLATE,
|
|
2077
|
+
CSS_TEMPLATE,
|
|
2078
|
+
GRAPHQL_TEMPLATE,
|
|
2079
|
+
TEMPLATE_STRING,
|
|
2080
|
+
COMMENT,
|
|
2081
|
+
// Skip numbers when they are part of a variable name
|
|
2082
|
+
{ match: /\$\d+/ },
|
|
2083
|
+
NUMBER,
|
|
2084
|
+
CLASS_REFERENCE,
|
|
2085
|
+
{
|
|
2086
|
+
className: "attr",
|
|
2087
|
+
begin: IDENT_RE$12 + regex.lookahead(":"),
|
|
2088
|
+
relevance: 0
|
|
2089
|
+
},
|
|
2090
|
+
FUNCTION_VARIABLE,
|
|
2091
|
+
{
|
|
2092
|
+
// "value" container
|
|
2093
|
+
begin: "(" + hljs.RE_STARTERS_RE + "|\\b(case|return|throw)\\b)\\s*",
|
|
2094
|
+
keywords: "return throw case",
|
|
2095
|
+
relevance: 0,
|
|
2096
|
+
contains: [
|
|
2097
|
+
COMMENT,
|
|
2098
|
+
hljs.REGEXP_MODE,
|
|
2099
|
+
{
|
|
2100
|
+
className: "function",
|
|
2101
|
+
// we have to count the parens to make sure we actually have the
|
|
2102
|
+
// correct bounding ( ) before the =>. There could be any number of
|
|
2103
|
+
// sub-expressions inside also surrounded by parens.
|
|
2104
|
+
begin: FUNC_LEAD_IN_RE,
|
|
2105
|
+
returnBegin: true,
|
|
2106
|
+
end: "\\s*=>",
|
|
2107
|
+
contains: [
|
|
2108
|
+
{
|
|
2109
|
+
className: "params",
|
|
2110
|
+
variants: [
|
|
2111
|
+
{
|
|
2112
|
+
begin: hljs.UNDERSCORE_IDENT_RE,
|
|
2113
|
+
relevance: 0
|
|
2114
|
+
},
|
|
2115
|
+
{
|
|
2116
|
+
className: null,
|
|
2117
|
+
begin: /\(\s*\)/,
|
|
2118
|
+
skip: true
|
|
2119
|
+
},
|
|
2120
|
+
{
|
|
2121
|
+
begin: /\(/,
|
|
2122
|
+
end: /\)/,
|
|
2123
|
+
excludeBegin: true,
|
|
2124
|
+
excludeEnd: true,
|
|
2125
|
+
keywords: KEYWORDS$12,
|
|
2126
|
+
contains: PARAMS_CONTAINS
|
|
2127
|
+
}
|
|
2128
|
+
]
|
|
2129
|
+
}
|
|
2130
|
+
]
|
|
2131
|
+
},
|
|
2132
|
+
{
|
|
2133
|
+
// could be a comma delimited list of params to a function call
|
|
2134
|
+
begin: /,/,
|
|
2135
|
+
relevance: 0
|
|
2136
|
+
},
|
|
2137
|
+
{
|
|
2138
|
+
match: /\s+/,
|
|
2139
|
+
relevance: 0
|
|
2140
|
+
},
|
|
2141
|
+
{
|
|
2142
|
+
// JSX
|
|
2143
|
+
variants: [
|
|
2144
|
+
{ begin: FRAGMENT.begin, end: FRAGMENT.end },
|
|
2145
|
+
{ match: XML_SELF_CLOSING },
|
|
2146
|
+
{
|
|
2147
|
+
begin: XML_TAG.begin,
|
|
2148
|
+
// we carefully check the opening tag to see if it truly
|
|
2149
|
+
// is a tag and not a false positive
|
|
2150
|
+
"on:begin": XML_TAG.isTrulyOpeningTag,
|
|
2151
|
+
end: XML_TAG.end
|
|
2152
|
+
}
|
|
2153
|
+
],
|
|
2154
|
+
subLanguage: "xml",
|
|
2155
|
+
contains: [
|
|
2156
|
+
{
|
|
2157
|
+
begin: XML_TAG.begin,
|
|
2158
|
+
end: XML_TAG.end,
|
|
2159
|
+
skip: true,
|
|
2160
|
+
contains: ["self"]
|
|
2161
|
+
}
|
|
2162
|
+
]
|
|
2163
|
+
}
|
|
2164
|
+
]
|
|
2165
|
+
},
|
|
2166
|
+
FUNCTION_DEFINITION,
|
|
2167
|
+
{
|
|
2168
|
+
// prevent this from getting swallowed up by function
|
|
2169
|
+
// since they appear "function like"
|
|
2170
|
+
beginKeywords: "while if switch catch for"
|
|
2171
|
+
},
|
|
2172
|
+
{
|
|
2173
|
+
// we have to count the parens to make sure we actually have the correct
|
|
2174
|
+
// bounding ( ). There could be any number of sub-expressions inside
|
|
2175
|
+
// also surrounded by parens.
|
|
2176
|
+
begin: "\\b(?!function)" + hljs.UNDERSCORE_IDENT_RE + "\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",
|
|
2177
|
+
// end parens
|
|
2178
|
+
returnBegin: true,
|
|
2179
|
+
label: "func.def",
|
|
2180
|
+
contains: [
|
|
2181
|
+
PARAMS,
|
|
2182
|
+
hljs.inherit(hljs.TITLE_MODE, { begin: IDENT_RE$12, className: "title.function" })
|
|
2183
|
+
]
|
|
2184
|
+
},
|
|
2185
|
+
// catch ... so it won't trigger the property rule below
|
|
2186
|
+
{
|
|
2187
|
+
match: /\.\.\./,
|
|
2188
|
+
relevance: 0
|
|
2189
|
+
},
|
|
2190
|
+
PROPERTY_ACCESS,
|
|
2191
|
+
// hack: prevents detection of keywords in some circumstances
|
|
2192
|
+
// .keyword()
|
|
2193
|
+
// $keyword = x
|
|
2194
|
+
{
|
|
2195
|
+
match: "\\$" + IDENT_RE$12,
|
|
2196
|
+
relevance: 0
|
|
2197
|
+
},
|
|
2198
|
+
{
|
|
2199
|
+
match: [/\bconstructor(?=\s*\()/],
|
|
2200
|
+
className: { 1: "title.function" },
|
|
2201
|
+
contains: [PARAMS]
|
|
2202
|
+
},
|
|
2203
|
+
FUNCTION_CALL,
|
|
2204
|
+
UPPER_CASE_CONSTANT,
|
|
2205
|
+
CLASS_OR_EXTENDS,
|
|
2206
|
+
GETTER_OR_SETTER,
|
|
2207
|
+
{
|
|
2208
|
+
match: /\$[(.]/
|
|
2209
|
+
// relevance booster for a pattern common to JS libs: `$(something)` and `$.something`
|
|
2210
|
+
}
|
|
2211
|
+
]
|
|
2212
|
+
};
|
|
2213
|
+
}
|
|
2214
|
+
function typescript(hljs) {
|
|
2215
|
+
const tsLanguage = javascript(hljs);
|
|
2216
|
+
const IDENT_RE$12 = IDENT_RE;
|
|
2217
|
+
const TYPES2 = [
|
|
2218
|
+
"any",
|
|
2219
|
+
"void",
|
|
2220
|
+
"number",
|
|
2221
|
+
"boolean",
|
|
2222
|
+
"string",
|
|
2223
|
+
"object",
|
|
2224
|
+
"never",
|
|
2225
|
+
"symbol",
|
|
2226
|
+
"bigint",
|
|
2227
|
+
"unknown"
|
|
2228
|
+
];
|
|
2229
|
+
const NAMESPACE = {
|
|
2230
|
+
beginKeywords: "namespace",
|
|
2231
|
+
end: /\{/,
|
|
2232
|
+
excludeEnd: true,
|
|
2233
|
+
contains: [tsLanguage.exports.CLASS_REFERENCE]
|
|
2234
|
+
};
|
|
2235
|
+
const INTERFACE = {
|
|
2236
|
+
beginKeywords: "interface",
|
|
2237
|
+
end: /\{/,
|
|
2238
|
+
excludeEnd: true,
|
|
2239
|
+
keywords: {
|
|
2240
|
+
keyword: "interface extends",
|
|
2241
|
+
built_in: TYPES2
|
|
2242
|
+
},
|
|
2243
|
+
contains: [tsLanguage.exports.CLASS_REFERENCE]
|
|
2244
|
+
};
|
|
2245
|
+
const USE_STRICT = {
|
|
2246
|
+
className: "meta",
|
|
2247
|
+
relevance: 10,
|
|
2248
|
+
begin: /^\s*['"]use strict['"]/
|
|
2249
|
+
};
|
|
2250
|
+
const TS_SPECIFIC_KEYWORDS = [
|
|
2251
|
+
"type",
|
|
2252
|
+
"namespace",
|
|
2253
|
+
"interface",
|
|
2254
|
+
"public",
|
|
2255
|
+
"private",
|
|
2256
|
+
"protected",
|
|
2257
|
+
"implements",
|
|
2258
|
+
"declare",
|
|
2259
|
+
"abstract",
|
|
2260
|
+
"readonly",
|
|
2261
|
+
"enum",
|
|
2262
|
+
"override"
|
|
2263
|
+
];
|
|
2264
|
+
const KEYWORDS$12 = {
|
|
2265
|
+
$pattern: IDENT_RE,
|
|
2266
|
+
keyword: KEYWORDS.concat(TS_SPECIFIC_KEYWORDS),
|
|
2267
|
+
literal: LITERALS,
|
|
2268
|
+
built_in: BUILT_INS.concat(TYPES2),
|
|
2269
|
+
"variable.language": BUILT_IN_VARIABLES
|
|
2270
|
+
};
|
|
2271
|
+
const DECORATOR = {
|
|
2272
|
+
className: "meta",
|
|
2273
|
+
begin: "@" + IDENT_RE$12
|
|
2274
|
+
};
|
|
2275
|
+
const swapMode = (mode, label, replacement) => {
|
|
2276
|
+
const indx = mode.contains.findIndex((m) => m.label === label);
|
|
2277
|
+
if (indx === -1) {
|
|
2278
|
+
throw new Error("can not find mode to replace");
|
|
2279
|
+
}
|
|
2280
|
+
mode.contains.splice(indx, 1, replacement);
|
|
2281
|
+
};
|
|
2282
|
+
Object.assign(tsLanguage.keywords, KEYWORDS$12);
|
|
2283
|
+
tsLanguage.exports.PARAMS_CONTAINS.push(DECORATOR);
|
|
2284
|
+
tsLanguage.contains = tsLanguage.contains.concat([
|
|
2285
|
+
DECORATOR,
|
|
2286
|
+
NAMESPACE,
|
|
2287
|
+
INTERFACE
|
|
2288
|
+
]);
|
|
2289
|
+
swapMode(tsLanguage, "shebang", hljs.SHEBANG());
|
|
2290
|
+
swapMode(tsLanguage, "use_strict", USE_STRICT);
|
|
2291
|
+
const functionDeclaration = tsLanguage.contains.find((m) => m.label === "func.def");
|
|
2292
|
+
functionDeclaration.relevance = 0;
|
|
2293
|
+
Object.assign(tsLanguage, {
|
|
2294
|
+
name: "TypeScript",
|
|
2295
|
+
aliases: [
|
|
2296
|
+
"ts",
|
|
2297
|
+
"tsx",
|
|
2298
|
+
"mts",
|
|
2299
|
+
"cts"
|
|
2300
|
+
]
|
|
2301
|
+
});
|
|
2302
|
+
return tsLanguage;
|
|
2303
|
+
}
|
|
2304
|
+
function xml(hljs) {
|
|
2305
|
+
const regex = hljs.regex;
|
|
2306
|
+
const TAG_NAME_RE = regex.concat(/[\p{L}_]/u, regex.optional(/[\p{L}0-9_.-]*:/u), /[\p{L}0-9_.-]*/u);
|
|
2307
|
+
const XML_IDENT_RE = /[\p{L}0-9._:-]+/u;
|
|
2308
|
+
const XML_ENTITIES = {
|
|
2309
|
+
className: "symbol",
|
|
2310
|
+
begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/
|
|
2311
|
+
};
|
|
2312
|
+
const XML_META_KEYWORDS = {
|
|
2313
|
+
begin: /\s/,
|
|
2314
|
+
contains: [
|
|
2315
|
+
{
|
|
2316
|
+
className: "keyword",
|
|
2317
|
+
begin: /#?[a-z_][a-z1-9_-]+/,
|
|
2318
|
+
illegal: /\n/
|
|
2319
|
+
}
|
|
2320
|
+
]
|
|
2321
|
+
};
|
|
2322
|
+
const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {
|
|
2323
|
+
begin: /\(/,
|
|
2324
|
+
end: /\)/
|
|
2325
|
+
});
|
|
2326
|
+
const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, { className: "string" });
|
|
2327
|
+
const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, { className: "string" });
|
|
2328
|
+
const TAG_INTERNALS = {
|
|
2329
|
+
endsWithParent: true,
|
|
2330
|
+
illegal: /</,
|
|
2331
|
+
relevance: 0,
|
|
2332
|
+
contains: [
|
|
2333
|
+
{
|
|
2334
|
+
className: "attr",
|
|
2335
|
+
begin: XML_IDENT_RE,
|
|
2336
|
+
relevance: 0
|
|
2337
|
+
},
|
|
2338
|
+
{
|
|
2339
|
+
begin: /=\s*/,
|
|
2340
|
+
relevance: 0,
|
|
2341
|
+
contains: [
|
|
2342
|
+
{
|
|
2343
|
+
className: "string",
|
|
2344
|
+
endsParent: true,
|
|
2345
|
+
variants: [
|
|
2346
|
+
{
|
|
2347
|
+
begin: /"/,
|
|
2348
|
+
end: /"/,
|
|
2349
|
+
contains: [XML_ENTITIES]
|
|
2350
|
+
},
|
|
2351
|
+
{
|
|
2352
|
+
begin: /'/,
|
|
2353
|
+
end: /'/,
|
|
2354
|
+
contains: [XML_ENTITIES]
|
|
2355
|
+
},
|
|
2356
|
+
{ begin: /[^\s"'=<>`]+/ }
|
|
2357
|
+
]
|
|
2358
|
+
}
|
|
2359
|
+
]
|
|
2360
|
+
}
|
|
2361
|
+
]
|
|
2362
|
+
};
|
|
2363
|
+
return {
|
|
2364
|
+
name: "HTML, XML",
|
|
2365
|
+
aliases: [
|
|
2366
|
+
"html",
|
|
2367
|
+
"xhtml",
|
|
2368
|
+
"rss",
|
|
2369
|
+
"atom",
|
|
2370
|
+
"xjb",
|
|
2371
|
+
"xsd",
|
|
2372
|
+
"xsl",
|
|
2373
|
+
"plist",
|
|
2374
|
+
"wsf",
|
|
2375
|
+
"svg"
|
|
2376
|
+
],
|
|
2377
|
+
case_insensitive: true,
|
|
2378
|
+
unicodeRegex: true,
|
|
2379
|
+
contains: [
|
|
2380
|
+
{
|
|
2381
|
+
className: "meta",
|
|
2382
|
+
begin: /<![a-z]/,
|
|
2383
|
+
end: />/,
|
|
2384
|
+
relevance: 10,
|
|
2385
|
+
contains: [
|
|
2386
|
+
XML_META_KEYWORDS,
|
|
2387
|
+
QUOTE_META_STRING_MODE,
|
|
2388
|
+
APOS_META_STRING_MODE,
|
|
2389
|
+
XML_META_PAR_KEYWORDS,
|
|
2390
|
+
{
|
|
2391
|
+
begin: /\[/,
|
|
2392
|
+
end: /\]/,
|
|
2393
|
+
contains: [
|
|
2394
|
+
{
|
|
2395
|
+
className: "meta",
|
|
2396
|
+
begin: /<![a-z]/,
|
|
2397
|
+
end: />/,
|
|
2398
|
+
contains: [
|
|
2399
|
+
XML_META_KEYWORDS,
|
|
2400
|
+
XML_META_PAR_KEYWORDS,
|
|
2401
|
+
QUOTE_META_STRING_MODE,
|
|
2402
|
+
APOS_META_STRING_MODE
|
|
2403
|
+
]
|
|
2404
|
+
}
|
|
2405
|
+
]
|
|
2406
|
+
}
|
|
2407
|
+
]
|
|
2408
|
+
},
|
|
2409
|
+
hljs.COMMENT(
|
|
2410
|
+
/<!--/,
|
|
2411
|
+
/-->/,
|
|
2412
|
+
{ relevance: 10 }
|
|
2413
|
+
),
|
|
2414
|
+
{
|
|
2415
|
+
begin: /<!\[CDATA\[/,
|
|
2416
|
+
end: /\]\]>/,
|
|
2417
|
+
relevance: 10
|
|
2418
|
+
},
|
|
2419
|
+
XML_ENTITIES,
|
|
2420
|
+
// xml processing instructions
|
|
2421
|
+
{
|
|
2422
|
+
className: "meta",
|
|
2423
|
+
end: /\?>/,
|
|
2424
|
+
variants: [
|
|
2425
|
+
{
|
|
2426
|
+
begin: /<\?xml/,
|
|
2427
|
+
relevance: 10,
|
|
2428
|
+
contains: [
|
|
2429
|
+
QUOTE_META_STRING_MODE
|
|
2430
|
+
]
|
|
2431
|
+
},
|
|
2432
|
+
{
|
|
2433
|
+
begin: /<\?[a-z][a-z0-9]+/
|
|
2434
|
+
}
|
|
2435
|
+
]
|
|
2436
|
+
},
|
|
2437
|
+
{
|
|
2438
|
+
className: "tag",
|
|
2439
|
+
/*
|
|
2440
|
+
The lookahead pattern (?=...) ensures that 'begin' only matches
|
|
2441
|
+
'<style' as a single word, followed by a whitespace or an
|
|
2442
|
+
ending bracket.
|
|
2443
|
+
*/
|
|
2444
|
+
begin: /<style(?=\s|>)/,
|
|
2445
|
+
end: />/,
|
|
2446
|
+
keywords: { name: "style" },
|
|
2447
|
+
contains: [TAG_INTERNALS],
|
|
2448
|
+
starts: {
|
|
2449
|
+
end: /<\/style>/,
|
|
2450
|
+
returnEnd: true,
|
|
2451
|
+
subLanguage: [
|
|
2452
|
+
"css",
|
|
2453
|
+
"xml"
|
|
2454
|
+
]
|
|
2455
|
+
}
|
|
2456
|
+
},
|
|
2457
|
+
{
|
|
2458
|
+
className: "tag",
|
|
2459
|
+
// See the comment in the <style tag about the lookahead pattern
|
|
2460
|
+
begin: /<script(?=\s|>)/,
|
|
2461
|
+
end: />/,
|
|
2462
|
+
keywords: { name: "script" },
|
|
2463
|
+
contains: [TAG_INTERNALS],
|
|
2464
|
+
starts: {
|
|
2465
|
+
end: /<\/script>/,
|
|
2466
|
+
returnEnd: true,
|
|
2467
|
+
subLanguage: [
|
|
2468
|
+
"javascript",
|
|
2469
|
+
"handlebars",
|
|
2470
|
+
"xml"
|
|
2471
|
+
]
|
|
2472
|
+
}
|
|
2473
|
+
},
|
|
2474
|
+
// we need this for now for jSX
|
|
2475
|
+
{
|
|
2476
|
+
className: "tag",
|
|
2477
|
+
begin: /<>|<\/>/
|
|
2478
|
+
},
|
|
2479
|
+
// open tag
|
|
2480
|
+
{
|
|
2481
|
+
className: "tag",
|
|
2482
|
+
begin: regex.concat(
|
|
2483
|
+
/</,
|
|
2484
|
+
regex.lookahead(regex.concat(
|
|
2485
|
+
TAG_NAME_RE,
|
|
2486
|
+
// <tag/>
|
|
2487
|
+
// <tag>
|
|
2488
|
+
// <tag ...
|
|
2489
|
+
regex.either(/\/>/, />/, /\s/)
|
|
2490
|
+
))
|
|
2491
|
+
),
|
|
2492
|
+
end: /\/?>/,
|
|
2493
|
+
contains: [
|
|
2494
|
+
{
|
|
2495
|
+
className: "name",
|
|
2496
|
+
begin: TAG_NAME_RE,
|
|
2497
|
+
relevance: 0,
|
|
2498
|
+
starts: TAG_INTERNALS
|
|
2499
|
+
}
|
|
2500
|
+
]
|
|
2501
|
+
},
|
|
2502
|
+
// close tag
|
|
2503
|
+
{
|
|
2504
|
+
className: "tag",
|
|
2505
|
+
begin: regex.concat(
|
|
2506
|
+
/<\//,
|
|
2507
|
+
regex.lookahead(regex.concat(
|
|
2508
|
+
TAG_NAME_RE,
|
|
2509
|
+
/>/
|
|
2510
|
+
))
|
|
2511
|
+
),
|
|
2512
|
+
contains: [
|
|
2513
|
+
{
|
|
2514
|
+
className: "name",
|
|
2515
|
+
begin: TAG_NAME_RE,
|
|
2516
|
+
relevance: 0
|
|
2517
|
+
},
|
|
2518
|
+
{
|
|
2519
|
+
begin: />/,
|
|
2520
|
+
relevance: 0,
|
|
2521
|
+
endsParent: true
|
|
2522
|
+
}
|
|
2523
|
+
]
|
|
2524
|
+
}
|
|
2525
|
+
]
|
|
2526
|
+
};
|
|
2527
|
+
}
|
|
2528
|
+
function useChat() {
|
|
2529
|
+
return inject(ChatSymbol);
|
|
2530
|
+
}
|
|
2531
|
+
function useOptions() {
|
|
2532
|
+
const options = inject(ChatOptionsSymbol);
|
|
2533
|
+
return {
|
|
2534
|
+
options
|
|
2535
|
+
};
|
|
2536
|
+
}
|
|
2537
|
+
function useI18n() {
|
|
2538
|
+
const { options } = useOptions();
|
|
2539
|
+
const language = (options == null ? void 0 : options.defaultLanguage) ?? "en";
|
|
2540
|
+
function t(key) {
|
|
2541
|
+
var _a, _b;
|
|
2542
|
+
const val = (_b = (_a = options == null ? void 0 : options.i18n) == null ? void 0 : _a[language]) == null ? void 0 : _b[key];
|
|
2543
|
+
if (isRef(val)) {
|
|
2544
|
+
return val.value;
|
|
2545
|
+
}
|
|
2546
|
+
return val ?? key;
|
|
2547
|
+
}
|
|
2548
|
+
function te(key) {
|
|
2549
|
+
var _a, _b;
|
|
2550
|
+
return !!((_b = (_a = options == null ? void 0 : options.i18n) == null ? void 0 : _a[language]) == null ? void 0 : _b[key]);
|
|
2551
|
+
}
|
|
2552
|
+
return { t, te };
|
|
2553
|
+
}
|
|
2554
|
+
const _hoisted_1$d = {
|
|
2555
|
+
viewBox: "0 0 24 24",
|
|
2556
|
+
width: "1.2em",
|
|
2557
|
+
height: "1.2em"
|
|
2558
|
+
};
|
|
2559
|
+
function render$7(_ctx, _cache) {
|
|
2560
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$d, _cache[0] || (_cache[0] = [
|
|
2561
|
+
createBaseVNode("path", {
|
|
2562
|
+
fill: "currentColor",
|
|
2563
|
+
d: "M20 6.91L17.09 4L12 9.09L6.91 4L4 6.91L9.09 12L4 17.09L6.91 20L12 14.91L17.09 20L20 17.09L14.91 12z"
|
|
2564
|
+
}, null, -1)
|
|
2565
|
+
]));
|
|
2566
|
+
}
|
|
2567
|
+
const IconDelete = { name: "mdi-closeThick", render: render$7 };
|
|
2568
|
+
const _hoisted_1$c = {
|
|
2569
|
+
viewBox: "0 0 24 24",
|
|
2570
|
+
width: "1.2em",
|
|
2571
|
+
height: "1.2em"
|
|
2572
|
+
};
|
|
2573
|
+
function render$6(_ctx, _cache) {
|
|
2574
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$c, _cache[0] || (_cache[0] = [
|
|
2575
|
+
createBaseVNode("path", {
|
|
2576
|
+
fill: "currentColor",
|
|
2577
|
+
d: "M13 9h5.5L13 3.5zM6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m0 18h12v-8l-4 4l-2-2zM8 9a2 2 0 0 0-2 2a2 2 0 0 0 2 2a2 2 0 0 0 2-2a2 2 0 0 0-2-2"
|
|
2578
|
+
}, null, -1)
|
|
2579
|
+
]));
|
|
2580
|
+
}
|
|
2581
|
+
const IconFileImage = { name: "mdi-fileImage", render: render$6 };
|
|
2582
|
+
const _hoisted_1$b = {
|
|
2583
|
+
viewBox: "0 0 24 24",
|
|
2584
|
+
width: "1.2em",
|
|
2585
|
+
height: "1.2em"
|
|
2586
|
+
};
|
|
2587
|
+
function render$5(_ctx, _cache) {
|
|
2588
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$b, _cache[0] || (_cache[0] = [
|
|
2589
|
+
createBaseVNode("path", {
|
|
2590
|
+
fill: "currentColor",
|
|
2591
|
+
d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8zm-1 11h-2v5a2 2 0 0 1-2 2a2 2 0 0 1-2-2a2 2 0 0 1 2-2c.4 0 .7.1 1 .3V11h3zm0-4V3.5L18.5 9z"
|
|
2592
|
+
}, null, -1)
|
|
2593
|
+
]));
|
|
2594
|
+
}
|
|
2595
|
+
const IconFileMusic = { name: "mdi-fileMusic", render: render$5 };
|
|
2596
|
+
const _hoisted_1$a = {
|
|
2597
|
+
viewBox: "0 0 24 24",
|
|
2598
|
+
width: "1.2em",
|
|
2599
|
+
height: "1.2em"
|
|
2600
|
+
};
|
|
2601
|
+
function render$4(_ctx, _cache) {
|
|
2602
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$a, _cache[0] || (_cache[0] = [
|
|
2603
|
+
createBaseVNode("path", {
|
|
2604
|
+
fill: "currentColor",
|
|
2605
|
+
d: "M13 9h5.5L13 3.5zM6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m9 16v-2H6v2zm3-4v-2H6v2z"
|
|
2606
|
+
}, null, -1)
|
|
2607
|
+
]));
|
|
2608
|
+
}
|
|
2609
|
+
const IconFileText = { name: "mdi-fileText", render: render$4 };
|
|
2610
|
+
const _hoisted_1$9 = {
|
|
2611
|
+
viewBox: "0 0 24 24",
|
|
2612
|
+
width: "1.2em",
|
|
2613
|
+
height: "1.2em"
|
|
2614
|
+
};
|
|
2615
|
+
function render$3(_ctx, _cache) {
|
|
2616
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$9, _cache[0] || (_cache[0] = [
|
|
2617
|
+
createBaseVNode("path", {
|
|
2618
|
+
fill: "currentColor",
|
|
2619
|
+
d: "M13 9h5.5L13 3.5zM6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m11 17v-6l-3 2.2V13H7v6h7v-2.2z"
|
|
2620
|
+
}, null, -1)
|
|
2621
|
+
]));
|
|
2622
|
+
}
|
|
2623
|
+
const IconFileVideo = { name: "mdi-fileVideo", render: render$3 };
|
|
2624
|
+
const _hoisted_1$8 = {
|
|
2625
|
+
viewBox: "0 0 24 24",
|
|
2626
|
+
width: "1.2em",
|
|
2627
|
+
height: "1.2em"
|
|
2628
|
+
};
|
|
2629
|
+
function render$2(_ctx, _cache) {
|
|
2630
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$8, _cache[0] || (_cache[0] = [
|
|
2631
|
+
createBaseVNode("path", {
|
|
2632
|
+
fill: "currentColor",
|
|
2633
|
+
d: "M14 3v2h3.59l-9.83 9.83l1.41 1.41L19 6.41V10h2V3m-2 16H5V5h7V3H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7h-2z"
|
|
2634
|
+
}, null, -1)
|
|
2635
|
+
]));
|
|
2636
|
+
}
|
|
2637
|
+
const IconPreview = { name: "mdi-openInNew", render: render$2 };
|
|
2638
|
+
const _hoisted_1$7 = { class: "chat-file-name" };
|
|
2639
|
+
const _sfc_main$9 = /* @__PURE__ */ defineComponent({
|
|
2640
|
+
__name: "ChatFile",
|
|
2641
|
+
props: {
|
|
2642
|
+
file: {},
|
|
2643
|
+
isRemovable: { type: Boolean },
|
|
2644
|
+
isPreviewable: { type: Boolean }
|
|
2645
|
+
},
|
|
2646
|
+
emits: ["remove"],
|
|
2647
|
+
setup(__props, { emit: __emit }) {
|
|
2648
|
+
const props = __props;
|
|
2649
|
+
const emit = __emit;
|
|
2650
|
+
const iconMapper = {
|
|
2651
|
+
document: IconFileText,
|
|
2652
|
+
audio: IconFileMusic,
|
|
2653
|
+
image: IconFileImage,
|
|
2654
|
+
video: IconFileVideo
|
|
2655
|
+
};
|
|
2656
|
+
const TypeIcon = computed(() => {
|
|
2657
|
+
var _a;
|
|
2658
|
+
const type = (_a = props.file) == null ? void 0 : _a.type.split("/")[0];
|
|
2659
|
+
return iconMapper[type] || IconFileText;
|
|
2660
|
+
});
|
|
2661
|
+
function onClick() {
|
|
2662
|
+
if (props.isPreviewable) {
|
|
2663
|
+
window.open(URL.createObjectURL(props.file));
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
function onDelete() {
|
|
2667
|
+
emit("remove", props.file);
|
|
2668
|
+
}
|
|
2669
|
+
return (_ctx, _cache) => {
|
|
2670
|
+
return openBlock(), createElementBlock("div", {
|
|
2671
|
+
class: "chat-file",
|
|
2672
|
+
onClick
|
|
2673
|
+
}, [
|
|
2674
|
+
createVNode(unref(TypeIcon)),
|
|
2675
|
+
createBaseVNode("p", _hoisted_1$7, toDisplayString(_ctx.file.name), 1),
|
|
2676
|
+
_ctx.isRemovable ? (openBlock(), createElementBlock("span", {
|
|
2677
|
+
key: 0,
|
|
2678
|
+
class: "chat-file-delete",
|
|
2679
|
+
onClick: withModifiers(onDelete, ["stop"])
|
|
2680
|
+
}, [
|
|
2681
|
+
createVNode(unref(IconDelete))
|
|
2682
|
+
])) : _ctx.isPreviewable ? (openBlock(), createBlock(unref(IconPreview), {
|
|
2683
|
+
key: 1,
|
|
2684
|
+
class: "chat-file-preview"
|
|
2685
|
+
})) : createCommentVNode("", true)
|
|
2686
|
+
]);
|
|
2687
|
+
};
|
|
2688
|
+
}
|
|
2689
|
+
});
|
|
2690
|
+
const ChatFile = /* @__PURE__ */ _export_sfc(_sfc_main$9, [["__scopeId", "data-v-70b9370d"]]);
|
|
2691
|
+
const _hoisted_1$6 = {
|
|
2692
|
+
key: 0,
|
|
2693
|
+
class: "chat-message-actions"
|
|
2694
|
+
};
|
|
2695
|
+
const _hoisted_2$2 = {
|
|
2696
|
+
key: 2,
|
|
2697
|
+
class: "chat-message-files"
|
|
2698
|
+
};
|
|
2699
|
+
const _sfc_main$8 = /* @__PURE__ */ defineComponent({
|
|
2700
|
+
__name: "Message",
|
|
2701
|
+
props: {
|
|
2702
|
+
message: {}
|
|
2703
|
+
},
|
|
2704
|
+
setup(__props, { expose: __expose }) {
|
|
2705
|
+
const props = __props;
|
|
2706
|
+
HighlightJS.registerLanguage("javascript", javascript$1);
|
|
2707
|
+
HighlightJS.registerLanguage("typescript", typescript);
|
|
2708
|
+
HighlightJS.registerLanguage("python", python);
|
|
2709
|
+
HighlightJS.registerLanguage("xml", xml);
|
|
2710
|
+
HighlightJS.registerLanguage("bash", bash);
|
|
2711
|
+
const { message } = toRefs(props);
|
|
2712
|
+
const { options } = useOptions();
|
|
2713
|
+
const messageContainer = ref(null);
|
|
2714
|
+
const fileSources = ref({});
|
|
2715
|
+
const messageText = computed(() => {
|
|
2716
|
+
return message.value.text || "<Empty response>";
|
|
2717
|
+
});
|
|
2718
|
+
const classes = computed(() => {
|
|
2719
|
+
return {
|
|
2720
|
+
"chat-message-from-user": message.value.sender === "user",
|
|
2721
|
+
"chat-message-from-bot": message.value.sender === "bot",
|
|
2722
|
+
"chat-message-transparent": message.value.transparent === true
|
|
2723
|
+
};
|
|
2724
|
+
});
|
|
2725
|
+
const linksNewTabPlugin = (vueMarkdownItInstance) => {
|
|
2726
|
+
vueMarkdownItInstance.use(markdownLink, {
|
|
2727
|
+
attrs: {
|
|
2728
|
+
target: "_blank",
|
|
2729
|
+
rel: "noopener"
|
|
2730
|
+
}
|
|
2731
|
+
});
|
|
2732
|
+
};
|
|
2733
|
+
const scrollToView = () => {
|
|
2734
|
+
var _a;
|
|
2735
|
+
if ((_a = messageContainer.value) == null ? void 0 : _a.scrollIntoView) {
|
|
2736
|
+
messageContainer.value.scrollIntoView({
|
|
2737
|
+
block: "start"
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2740
|
+
};
|
|
2741
|
+
const markdownOptions = {
|
|
2742
|
+
highlight(str, lang) {
|
|
2743
|
+
if (lang && HighlightJS.getLanguage(lang)) {
|
|
2744
|
+
try {
|
|
2745
|
+
return HighlightJS.highlight(str, { language: lang }).value;
|
|
2746
|
+
} catch {
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
return "";
|
|
2750
|
+
}
|
|
2751
|
+
};
|
|
2752
|
+
const messageComponents = { ...(options == null ? void 0 : options.messageComponents) ?? {} };
|
|
2753
|
+
__expose({ scrollToView });
|
|
2754
|
+
const readFileAsDataURL = async (file) => await new Promise((resolve, reject) => {
|
|
2755
|
+
const reader = new FileReader();
|
|
2756
|
+
reader.onload = () => resolve(reader.result);
|
|
2757
|
+
reader.onerror = reject;
|
|
2758
|
+
reader.readAsDataURL(file);
|
|
2759
|
+
});
|
|
2760
|
+
onMounted(async () => {
|
|
2761
|
+
if (message.value.files) {
|
|
2762
|
+
for (const file of message.value.files) {
|
|
2763
|
+
try {
|
|
2764
|
+
const dataURL = await readFileAsDataURL(file);
|
|
2765
|
+
fileSources.value[file.name] = dataURL;
|
|
2766
|
+
} catch (error) {
|
|
2767
|
+
console.error("Error reading file:", error);
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
});
|
|
2772
|
+
return (_ctx, _cache) => {
|
|
2773
|
+
return openBlock(), createElementBlock("div", {
|
|
2774
|
+
ref_key: "messageContainer",
|
|
2775
|
+
ref: messageContainer,
|
|
2776
|
+
class: normalizeClass(["chat-message", classes.value])
|
|
2777
|
+
}, [
|
|
2778
|
+
_ctx.$slots.beforeMessage ? (openBlock(), createElementBlock("div", _hoisted_1$6, [
|
|
2779
|
+
renderSlot(_ctx.$slots, "beforeMessage", normalizeProps(guardReactiveProps({ message: unref(message) })))
|
|
2780
|
+
])) : createCommentVNode("", true),
|
|
2781
|
+
renderSlot(_ctx.$slots, "default", {}, () => [
|
|
2782
|
+
unref(message).type === "component" && messageComponents[unref(message).key] ? (openBlock(), createBlock(resolveDynamicComponent(messageComponents[unref(message).key]), normalizeProps(mergeProps({ key: 0 }, unref(message).arguments)), null, 16)) : (openBlock(), createBlock(unref(VueMarkdown), {
|
|
2783
|
+
key: 1,
|
|
2784
|
+
class: "chat-message-markdown",
|
|
2785
|
+
source: messageText.value,
|
|
2786
|
+
options: markdownOptions,
|
|
2787
|
+
plugins: [linksNewTabPlugin]
|
|
2788
|
+
}, null, 8, ["source", "plugins"])),
|
|
2789
|
+
(unref(message).files ?? []).length > 0 ? (openBlock(), createElementBlock("div", _hoisted_2$2, [
|
|
2790
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(message).files ?? [], (file) => {
|
|
2791
|
+
return openBlock(), createElementBlock("div", {
|
|
2792
|
+
key: file.name,
|
|
2793
|
+
class: "chat-message-file"
|
|
2794
|
+
}, [
|
|
2795
|
+
createVNode(ChatFile, {
|
|
2796
|
+
file,
|
|
2797
|
+
"is-removable": false,
|
|
2798
|
+
"is-previewable": true
|
|
2799
|
+
}, null, 8, ["file"])
|
|
2800
|
+
]);
|
|
2801
|
+
}), 128))
|
|
2802
|
+
])) : createCommentVNode("", true)
|
|
2803
|
+
])
|
|
2804
|
+
], 2);
|
|
2805
|
+
};
|
|
2806
|
+
}
|
|
2807
|
+
});
|
|
2808
|
+
const _hoisted_1$5 = {
|
|
2809
|
+
viewBox: "0 0 24 24",
|
|
2810
|
+
width: "1.2em",
|
|
2811
|
+
height: "1.2em"
|
|
2812
|
+
};
|
|
2813
|
+
function render$1(_ctx, _cache) {
|
|
2814
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$5, _cache[0] || (_cache[0] = [
|
|
2815
|
+
createBaseVNode("path", {
|
|
2816
|
+
fill: "currentColor",
|
|
2817
|
+
d: "M16.5 6v11.5a4 4 0 0 1-4 4a4 4 0 0 1-4-4V5A2.5 2.5 0 0 1 11 2.5A2.5 2.5 0 0 1 13.5 5v10.5a1 1 0 0 1-1 1a1 1 0 0 1-1-1V6H10v9.5a2.5 2.5 0 0 0 2.5 2.5a2.5 2.5 0 0 0 2.5-2.5V5a4 4 0 0 0-4-4a4 4 0 0 0-4 4v12.5a5.5 5.5 0 0 0 5.5 5.5a5.5 5.5 0 0 0 5.5-5.5V6z"
|
|
2818
|
+
}, null, -1)
|
|
2819
|
+
]));
|
|
2820
|
+
}
|
|
2821
|
+
const IconPaperclip = { name: "mdi-paperclip", render: render$1 };
|
|
2822
|
+
const _hoisted_1$4 = {
|
|
2823
|
+
viewBox: "0 0 24 24",
|
|
2824
|
+
width: "1.2em",
|
|
2825
|
+
height: "1.2em"
|
|
2826
|
+
};
|
|
2827
|
+
function render(_ctx, _cache) {
|
|
2828
|
+
return openBlock(), createElementBlock("svg", _hoisted_1$4, _cache[0] || (_cache[0] = [
|
|
2829
|
+
createBaseVNode("path", {
|
|
2830
|
+
fill: "currentColor",
|
|
2831
|
+
d: "m2 21l21-9L2 3v7l15 2l-15 2z"
|
|
2832
|
+
}, null, -1)
|
|
2833
|
+
]));
|
|
2834
|
+
}
|
|
2835
|
+
const IconSend = { name: "mdi-send", render };
|
|
2836
|
+
const _hoisted_1$3 = { class: "chat-inputs" };
|
|
2837
|
+
const _hoisted_2$1 = ["disabled", "placeholder"];
|
|
2838
|
+
const _hoisted_3 = { class: "chat-inputs-controls" };
|
|
2839
|
+
const _hoisted_4 = ["disabled"];
|
|
2840
|
+
const _hoisted_5 = ["disabled"];
|
|
2841
|
+
const _hoisted_6 = {
|
|
2842
|
+
key: 0,
|
|
2843
|
+
class: "chat-files"
|
|
2844
|
+
};
|
|
2845
|
+
const _sfc_main$7 = /* @__PURE__ */ defineComponent({
|
|
2846
|
+
__name: "Input",
|
|
2847
|
+
props: {
|
|
2848
|
+
placeholder: { default: "inputPlaceholder" }
|
|
2849
|
+
},
|
|
2850
|
+
emits: ["arrowKeyDown"],
|
|
2851
|
+
setup(__props, { emit: __emit }) {
|
|
2852
|
+
const props = __props;
|
|
2853
|
+
const { t } = useI18n();
|
|
2854
|
+
const emit = __emit;
|
|
2855
|
+
const { options } = useOptions();
|
|
2856
|
+
const chatStore = useChat();
|
|
2857
|
+
const { waitingForResponse } = chatStore;
|
|
2858
|
+
const files = ref(null);
|
|
2859
|
+
const chatTextArea = ref(null);
|
|
2860
|
+
const input = ref("");
|
|
2861
|
+
const isSubmitting = ref(false);
|
|
2862
|
+
const resizeObserver = ref(null);
|
|
2863
|
+
const isSubmitDisabled = computed(() => {
|
|
2864
|
+
var _a;
|
|
2865
|
+
return input.value === "" || waitingForResponse.value || ((_a = options.disabled) == null ? void 0 : _a.value) === true;
|
|
2866
|
+
});
|
|
2867
|
+
const isInputDisabled = computed(() => {
|
|
2868
|
+
var _a;
|
|
2869
|
+
return ((_a = options.disabled) == null ? void 0 : _a.value) === true;
|
|
2870
|
+
});
|
|
2871
|
+
const isFileUploadDisabled = computed(
|
|
2872
|
+
() => {
|
|
2873
|
+
var _a;
|
|
2874
|
+
return isFileUploadAllowed.value && waitingForResponse.value && !((_a = options.disabled) == null ? void 0 : _a.value);
|
|
2875
|
+
}
|
|
2876
|
+
);
|
|
2877
|
+
const isFileUploadAllowed = computed(() => unref(options.allowFileUploads) === true);
|
|
2878
|
+
const allowedFileTypes = computed(() => unref(options.allowedFilesMimeTypes));
|
|
2879
|
+
const styleVars = computed(() => {
|
|
2880
|
+
const controlsCount = isFileUploadAllowed.value ? 2 : 1;
|
|
2881
|
+
return {
|
|
2882
|
+
"--controls-count": controlsCount
|
|
2883
|
+
};
|
|
2884
|
+
});
|
|
2885
|
+
const {
|
|
2886
|
+
open: openFileDialog,
|
|
2887
|
+
reset: resetFileDialog,
|
|
2888
|
+
onChange
|
|
2889
|
+
} = useFileDialog({
|
|
2890
|
+
multiple: true,
|
|
2891
|
+
reset: false
|
|
2892
|
+
});
|
|
2893
|
+
onChange((newFiles) => {
|
|
2894
|
+
if (!newFiles) return;
|
|
2895
|
+
const newFilesDT = new DataTransfer();
|
|
2896
|
+
if (files.value) {
|
|
2897
|
+
for (let i = 0; i < files.value.length; i++) {
|
|
2898
|
+
newFilesDT.items.add(files.value[i]);
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
for (let i = 0; i < newFiles.length; i++) {
|
|
2902
|
+
newFilesDT.items.add(newFiles[i]);
|
|
2903
|
+
}
|
|
2904
|
+
files.value = newFilesDT.files;
|
|
2905
|
+
});
|
|
2906
|
+
onMounted(() => {
|
|
2907
|
+
chatEventBus.on("focusInput", focusChatInput);
|
|
2908
|
+
chatEventBus.on("blurInput", blurChatInput);
|
|
2909
|
+
chatEventBus.on("setInputValue", setInputValue);
|
|
2910
|
+
if (chatTextArea.value) {
|
|
2911
|
+
resizeObserver.value = new ResizeObserver((entries) => {
|
|
2912
|
+
for (const entry of entries) {
|
|
2913
|
+
if (entry.target === chatTextArea.value) {
|
|
2914
|
+
adjustHeight({ target: chatTextArea.value });
|
|
2915
|
+
}
|
|
2916
|
+
}
|
|
2917
|
+
});
|
|
2918
|
+
resizeObserver.value.observe(chatTextArea.value);
|
|
2919
|
+
}
|
|
2920
|
+
});
|
|
2921
|
+
onUnmounted(() => {
|
|
2922
|
+
chatEventBus.off("focusInput", focusChatInput);
|
|
2923
|
+
chatEventBus.off("blurInput", blurChatInput);
|
|
2924
|
+
chatEventBus.off("setInputValue", setInputValue);
|
|
2925
|
+
if (resizeObserver.value) {
|
|
2926
|
+
resizeObserver.value.disconnect();
|
|
2927
|
+
resizeObserver.value = null;
|
|
2928
|
+
}
|
|
2929
|
+
});
|
|
2930
|
+
function blurChatInput() {
|
|
2931
|
+
if (chatTextArea.value) {
|
|
2932
|
+
chatTextArea.value.blur();
|
|
2933
|
+
}
|
|
2934
|
+
}
|
|
2935
|
+
function focusChatInput() {
|
|
2936
|
+
if (chatTextArea.value) {
|
|
2937
|
+
chatTextArea.value.focus();
|
|
2938
|
+
}
|
|
2939
|
+
}
|
|
2940
|
+
function setInputValue(value) {
|
|
2941
|
+
input.value = value;
|
|
2942
|
+
focusChatInput();
|
|
2943
|
+
}
|
|
2944
|
+
async function onSubmit(event) {
|
|
2945
|
+
event.preventDefault();
|
|
2946
|
+
if (isSubmitDisabled.value) {
|
|
2947
|
+
return;
|
|
2948
|
+
}
|
|
2949
|
+
const messageText = input.value;
|
|
2950
|
+
input.value = "";
|
|
2951
|
+
isSubmitting.value = true;
|
|
2952
|
+
await chatStore.sendMessage(messageText, Array.from(files.value ?? []));
|
|
2953
|
+
isSubmitting.value = false;
|
|
2954
|
+
resetFileDialog();
|
|
2955
|
+
files.value = null;
|
|
2956
|
+
}
|
|
2957
|
+
async function onSubmitKeydown(event) {
|
|
2958
|
+
if (event.shiftKey) {
|
|
2959
|
+
return;
|
|
2960
|
+
}
|
|
2961
|
+
await onSubmit(event);
|
|
2962
|
+
adjustHeight({ target: chatTextArea.value });
|
|
2963
|
+
}
|
|
2964
|
+
function onFileRemove(file) {
|
|
2965
|
+
if (!files.value) return;
|
|
2966
|
+
const dt = new DataTransfer();
|
|
2967
|
+
for (let i = 0; i < files.value.length; i++) {
|
|
2968
|
+
const currentFile = files.value[i];
|
|
2969
|
+
if (file.name !== currentFile.name) dt.items.add(currentFile);
|
|
2970
|
+
}
|
|
2971
|
+
resetFileDialog();
|
|
2972
|
+
files.value = dt.files;
|
|
2973
|
+
}
|
|
2974
|
+
function onKeyDown(event) {
|
|
2975
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown") {
|
|
2976
|
+
event.preventDefault();
|
|
2977
|
+
emit("arrowKeyDown", {
|
|
2978
|
+
key: event.key,
|
|
2979
|
+
currentInputValue: input.value
|
|
2980
|
+
});
|
|
2981
|
+
}
|
|
2982
|
+
}
|
|
2983
|
+
function onOpenFileDialog() {
|
|
2984
|
+
if (isFileUploadDisabled.value) return;
|
|
2985
|
+
openFileDialog({ accept: unref(allowedFileTypes) });
|
|
2986
|
+
}
|
|
2987
|
+
function adjustHeight(event) {
|
|
2988
|
+
const textarea = event.target;
|
|
2989
|
+
textarea.style.height = "var(--chat--textarea--height)";
|
|
2990
|
+
const newHeight = Math.min(textarea.scrollHeight, 480);
|
|
2991
|
+
textarea.style.height = `${newHeight}px`;
|
|
2992
|
+
}
|
|
2993
|
+
return (_ctx, _cache) => {
|
|
2994
|
+
var _a;
|
|
2995
|
+
return openBlock(), createElementBlock("div", {
|
|
2996
|
+
class: "chat-input",
|
|
2997
|
+
style: normalizeStyle(styleVars.value),
|
|
2998
|
+
onKeydown: withModifiers(onKeyDown, ["stop"])
|
|
2999
|
+
}, [
|
|
3000
|
+
createBaseVNode("div", _hoisted_1$3, [
|
|
3001
|
+
withDirectives(createBaseVNode("textarea", {
|
|
3002
|
+
ref_key: "chatTextArea",
|
|
3003
|
+
ref: chatTextArea,
|
|
3004
|
+
"data-test-id": "chat-input",
|
|
3005
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => input.value = $event),
|
|
3006
|
+
disabled: isInputDisabled.value,
|
|
3007
|
+
placeholder: unref(t)(props.placeholder),
|
|
3008
|
+
onKeydown: withKeys(onSubmitKeydown, ["enter"]),
|
|
3009
|
+
onInput: adjustHeight,
|
|
3010
|
+
onMousedown: adjustHeight,
|
|
3011
|
+
onFocus: adjustHeight
|
|
3012
|
+
}, null, 40, _hoisted_2$1), [
|
|
3013
|
+
[vModelText, input.value]
|
|
3014
|
+
]),
|
|
3015
|
+
createBaseVNode("div", _hoisted_3, [
|
|
3016
|
+
isFileUploadAllowed.value ? (openBlock(), createElementBlock("button", {
|
|
3017
|
+
key: 0,
|
|
3018
|
+
disabled: isFileUploadDisabled.value,
|
|
3019
|
+
class: "chat-input-file-button",
|
|
3020
|
+
"data-test-id": "chat-attach-file-button",
|
|
3021
|
+
onClick: onOpenFileDialog
|
|
3022
|
+
}, [
|
|
3023
|
+
createVNode(unref(IconPaperclip), {
|
|
3024
|
+
height: "24",
|
|
3025
|
+
width: "24"
|
|
3026
|
+
})
|
|
3027
|
+
], 8, _hoisted_4)) : createCommentVNode("", true),
|
|
3028
|
+
createBaseVNode("button", {
|
|
3029
|
+
disabled: isSubmitDisabled.value,
|
|
3030
|
+
class: "chat-input-send-button",
|
|
3031
|
+
onClick: onSubmit
|
|
3032
|
+
}, [
|
|
3033
|
+
createVNode(unref(IconSend), {
|
|
3034
|
+
height: "24",
|
|
3035
|
+
width: "24"
|
|
3036
|
+
})
|
|
3037
|
+
], 8, _hoisted_5)
|
|
3038
|
+
])
|
|
3039
|
+
]),
|
|
3040
|
+
((_a = files.value) == null ? void 0 : _a.length) && !isSubmitting.value ? (openBlock(), createElementBlock("div", _hoisted_6, [
|
|
3041
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(files.value, (file) => {
|
|
3042
|
+
return openBlock(), createBlock(ChatFile, {
|
|
3043
|
+
key: file.name,
|
|
3044
|
+
file,
|
|
3045
|
+
"is-removable": true,
|
|
3046
|
+
"is-previewable": true,
|
|
3047
|
+
onRemove: onFileRemove
|
|
3048
|
+
}, null, 8, ["file"]);
|
|
3049
|
+
}), 128))
|
|
3050
|
+
])) : createCommentVNode("", true)
|
|
3051
|
+
], 36);
|
|
3052
|
+
};
|
|
3053
|
+
}
|
|
3054
|
+
});
|
|
3055
|
+
const ChatInput = /* @__PURE__ */ _export_sfc(_sfc_main$7, [["__scopeId", "data-v-797d44b4"]]);
|
|
3056
|
+
const _sfc_main$6 = /* @__PURE__ */ defineComponent({
|
|
3057
|
+
__name: "MessageTyping",
|
|
3058
|
+
props: {
|
|
3059
|
+
animation: { default: "bouncing" }
|
|
3060
|
+
},
|
|
3061
|
+
setup(__props) {
|
|
3062
|
+
const props = __props;
|
|
3063
|
+
const message = {
|
|
3064
|
+
id: "typing",
|
|
3065
|
+
text: "",
|
|
3066
|
+
sender: "bot",
|
|
3067
|
+
createdAt: ""
|
|
3068
|
+
};
|
|
3069
|
+
const messageContainer = ref();
|
|
3070
|
+
const classes = computed(() => {
|
|
3071
|
+
return {
|
|
3072
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
3073
|
+
"chat-message-typing": true,
|
|
3074
|
+
[`chat-message-typing-animation-${props.animation}`]: true
|
|
3075
|
+
};
|
|
3076
|
+
});
|
|
3077
|
+
onMounted(() => {
|
|
3078
|
+
var _a;
|
|
3079
|
+
(_a = messageContainer.value) == null ? void 0 : _a.scrollToView();
|
|
3080
|
+
});
|
|
3081
|
+
return (_ctx, _cache) => {
|
|
3082
|
+
return openBlock(), createBlock(unref(_sfc_main$8), {
|
|
3083
|
+
ref_key: "messageContainer",
|
|
3084
|
+
ref: messageContainer,
|
|
3085
|
+
class: normalizeClass(classes.value),
|
|
3086
|
+
message,
|
|
3087
|
+
"data-test-id": "chat-message-typing"
|
|
3088
|
+
}, {
|
|
3089
|
+
default: withCtx(() => _cache[0] || (_cache[0] = [
|
|
3090
|
+
createBaseVNode("div", { class: "chat-message-typing-body" }, [
|
|
3091
|
+
createBaseVNode("span", { class: "chat-message-typing-circle" }),
|
|
3092
|
+
createBaseVNode("span", { class: "chat-message-typing-circle" }),
|
|
3093
|
+
createBaseVNode("span", { class: "chat-message-typing-circle" })
|
|
3094
|
+
], -1)
|
|
3095
|
+
])),
|
|
3096
|
+
_: 1
|
|
3097
|
+
}, 8, ["class"]);
|
|
3098
|
+
};
|
|
3099
|
+
}
|
|
3100
|
+
});
|
|
3101
|
+
const _hoisted_1$2 = { class: "chat-messages-list" };
|
|
3102
|
+
const _sfc_main$5 = /* @__PURE__ */ defineComponent({
|
|
3103
|
+
__name: "MessagesList",
|
|
3104
|
+
props: {
|
|
3105
|
+
messages: {}
|
|
3106
|
+
},
|
|
3107
|
+
setup(__props) {
|
|
3108
|
+
const chatStore = useChat();
|
|
3109
|
+
const messageComponents = ref([]);
|
|
3110
|
+
const { initialMessages, waitingForResponse } = chatStore;
|
|
3111
|
+
watch(
|
|
3112
|
+
() => messageComponents.value.length,
|
|
3113
|
+
() => {
|
|
3114
|
+
const lastMessageComponent = messageComponents.value[messageComponents.value.length - 1];
|
|
3115
|
+
if (lastMessageComponent) {
|
|
3116
|
+
lastMessageComponent.scrollToView();
|
|
3117
|
+
}
|
|
3118
|
+
}
|
|
3119
|
+
);
|
|
3120
|
+
return (_ctx, _cache) => {
|
|
3121
|
+
return openBlock(), createElementBlock("div", _hoisted_1$2, [
|
|
3122
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(initialMessages), (initialMessage) => {
|
|
3123
|
+
return openBlock(), createBlock(_sfc_main$8, {
|
|
3124
|
+
key: initialMessage.id,
|
|
3125
|
+
message: initialMessage
|
|
3126
|
+
}, null, 8, ["message"]);
|
|
3127
|
+
}), 128)),
|
|
3128
|
+
(openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.messages, (message) => {
|
|
3129
|
+
return openBlock(), createBlock(_sfc_main$8, {
|
|
3130
|
+
key: message.id,
|
|
3131
|
+
ref_for: true,
|
|
3132
|
+
ref_key: "messageComponents",
|
|
3133
|
+
ref: messageComponents,
|
|
3134
|
+
message
|
|
3135
|
+
}, {
|
|
3136
|
+
beforeMessage: withCtx(({ message: message2 }) => [
|
|
3137
|
+
renderSlot(_ctx.$slots, "beforeMessage", mergeProps({ ref_for: true }, { message: message2 }))
|
|
3138
|
+
]),
|
|
3139
|
+
_: 2
|
|
3140
|
+
}, 1032, ["message"]);
|
|
3141
|
+
}), 128)),
|
|
3142
|
+
unref(waitingForResponse) ? (openBlock(), createBlock(_sfc_main$6, { key: 0 })) : createCommentVNode("", true)
|
|
3143
|
+
]);
|
|
3144
|
+
};
|
|
3145
|
+
}
|
|
3146
|
+
});
|
|
3147
|
+
const _sfc_main$4 = /* @__PURE__ */ defineComponent({
|
|
3148
|
+
__name: "MessageOptionTooltip",
|
|
3149
|
+
props: {
|
|
3150
|
+
placement: {
|
|
3151
|
+
type: String,
|
|
3152
|
+
default: "top"
|
|
3153
|
+
}
|
|
3154
|
+
},
|
|
3155
|
+
setup(__props) {
|
|
3156
|
+
return (_ctx, _cache) => {
|
|
3157
|
+
const _component_n8n_icon = resolveComponent("n8n-icon");
|
|
3158
|
+
const _component_n8n_tooltip = resolveComponent("n8n-tooltip");
|
|
3159
|
+
return openBlock(), createElementBlock("div", {
|
|
3160
|
+
class: normalizeClass(_ctx.$style.container)
|
|
3161
|
+
}, [
|
|
3162
|
+
createVNode(_component_n8n_tooltip, { placement: __props.placement }, {
|
|
3163
|
+
content: withCtx(() => [
|
|
3164
|
+
renderSlot(_ctx.$slots, "default")
|
|
3165
|
+
]),
|
|
3166
|
+
default: withCtx(() => [
|
|
3167
|
+
createBaseVNode("span", {
|
|
3168
|
+
class: normalizeClass(_ctx.$style.icon)
|
|
3169
|
+
}, [
|
|
3170
|
+
createVNode(_component_n8n_icon, {
|
|
3171
|
+
icon: "info",
|
|
3172
|
+
size: "xsmall"
|
|
3173
|
+
})
|
|
3174
|
+
], 2)
|
|
3175
|
+
]),
|
|
3176
|
+
_: 3
|
|
3177
|
+
}, 8, ["placement"])
|
|
3178
|
+
], 2);
|
|
3179
|
+
};
|
|
3180
|
+
}
|
|
3181
|
+
});
|
|
3182
|
+
const container$2 = "_container_12y0i_1";
|
|
3183
|
+
const icon$1 = "_icon_12y0i_7";
|
|
3184
|
+
const style0$4 = {
|
|
3185
|
+
container: container$2,
|
|
3186
|
+
icon: icon$1
|
|
3187
|
+
};
|
|
3188
|
+
const cssModules$4 = {
|
|
3189
|
+
"$style": style0$4
|
|
3190
|
+
};
|
|
3191
|
+
const MessageOptionTooltip = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__cssModules", cssModules$4]]);
|
|
3192
|
+
const _sfc_main$3 = /* @__PURE__ */ defineComponent({
|
|
3193
|
+
__name: "MessageOptionAction",
|
|
3194
|
+
props: {
|
|
3195
|
+
label: {
|
|
3196
|
+
type: String,
|
|
3197
|
+
required: true
|
|
3198
|
+
},
|
|
3199
|
+
icon: {
|
|
3200
|
+
type: String,
|
|
3201
|
+
required: true
|
|
3202
|
+
},
|
|
3203
|
+
placement: {
|
|
3204
|
+
type: String,
|
|
3205
|
+
default: "top"
|
|
3206
|
+
}
|
|
3207
|
+
},
|
|
3208
|
+
setup(__props) {
|
|
3209
|
+
return (_ctx, _cache) => {
|
|
3210
|
+
const _component_n8n_icon = resolveComponent("n8n-icon");
|
|
3211
|
+
const _component_n8n_tooltip = resolveComponent("n8n-tooltip");
|
|
3212
|
+
return openBlock(), createElementBlock("div", {
|
|
3213
|
+
class: normalizeClass(_ctx.$style.container)
|
|
3214
|
+
}, [
|
|
3215
|
+
createVNode(_component_n8n_tooltip, { placement: __props.placement }, {
|
|
3216
|
+
content: withCtx(() => [
|
|
3217
|
+
createTextVNode(toDisplayString(__props.label), 1)
|
|
3218
|
+
]),
|
|
3219
|
+
default: withCtx(() => [
|
|
3220
|
+
createVNode(_component_n8n_icon, {
|
|
3221
|
+
class: normalizeClass(_ctx.$style.icon),
|
|
3222
|
+
icon: __props.icon,
|
|
3223
|
+
size: "xsmall",
|
|
3224
|
+
onClick: _ctx.$attrs.onClick
|
|
3225
|
+
}, null, 8, ["class", "icon", "onClick"])
|
|
3226
|
+
]),
|
|
3227
|
+
_: 1
|
|
3228
|
+
}, 8, ["placement"])
|
|
3229
|
+
], 2);
|
|
3230
|
+
};
|
|
3231
|
+
}
|
|
3232
|
+
});
|
|
3233
|
+
const container$1 = "_container_1as83_1";
|
|
3234
|
+
const icon = "_icon_1as83_7";
|
|
3235
|
+
const style0$3 = {
|
|
3236
|
+
container: container$1,
|
|
3237
|
+
icon
|
|
3238
|
+
};
|
|
3239
|
+
const cssModules$3 = {
|
|
3240
|
+
"$style": style0$3
|
|
3241
|
+
};
|
|
3242
|
+
const MessageOptionAction = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["__cssModules", cssModules$3]]);
|
|
3243
|
+
const _hoisted_1$1 = ["onClick"];
|
|
3244
|
+
const _sfc_main$2 = /* @__PURE__ */ defineComponent({
|
|
3245
|
+
__name: "ChatMessagesPanel",
|
|
3246
|
+
props: {
|
|
3247
|
+
pastChatMessages: {},
|
|
3248
|
+
messages: {},
|
|
3249
|
+
sessionId: {}
|
|
3250
|
+
},
|
|
3251
|
+
emits: ["displayExecution", "sendMessage", "refreshSession"],
|
|
3252
|
+
setup(__props, { emit: __emit }) {
|
|
3253
|
+
const props = __props;
|
|
3254
|
+
const emit = __emit;
|
|
3255
|
+
const messageComposable = useMessage();
|
|
3256
|
+
const clipboard = useClipboard();
|
|
3257
|
+
const locale = useI18n$1();
|
|
3258
|
+
const toast = useToast();
|
|
3259
|
+
const previousMessageIndex = ref(0);
|
|
3260
|
+
const inputPlaceholder = computed(() => {
|
|
3261
|
+
if (props.messages.length > 0) {
|
|
3262
|
+
return locale.baseText("chat.window.chat.placeholder");
|
|
3263
|
+
}
|
|
3264
|
+
return locale.baseText("chat.window.chat.placeholderPristine");
|
|
3265
|
+
});
|
|
3266
|
+
function isTextMessage(message) {
|
|
3267
|
+
return message.type === "text" || !message.type;
|
|
3268
|
+
}
|
|
3269
|
+
function repostMessage(message) {
|
|
3270
|
+
void sendMessage(message.text);
|
|
3271
|
+
}
|
|
3272
|
+
function reuseMessage(message) {
|
|
3273
|
+
chatEventBus.emit("setInputValue", message.text);
|
|
3274
|
+
}
|
|
3275
|
+
function sendMessage(message) {
|
|
3276
|
+
previousMessageIndex.value = 0;
|
|
3277
|
+
emit("sendMessage", message);
|
|
3278
|
+
}
|
|
3279
|
+
async function onRefreshSession() {
|
|
3280
|
+
if (props.messages.length === 0) {
|
|
3281
|
+
emit("refreshSession");
|
|
3282
|
+
return;
|
|
3283
|
+
}
|
|
3284
|
+
const confirmResult = await messageComposable.confirm(
|
|
3285
|
+
locale.baseText("chat.window.session.reset.warning"),
|
|
3286
|
+
{
|
|
3287
|
+
title: locale.baseText("chat.window.session.reset.title"),
|
|
3288
|
+
type: "warning",
|
|
3289
|
+
confirmButtonText: locale.baseText("chat.window.session.reset.confirm"),
|
|
3290
|
+
showClose: true
|
|
3291
|
+
}
|
|
3292
|
+
);
|
|
3293
|
+
if (confirmResult === MODAL_CONFIRM) {
|
|
3294
|
+
emit("refreshSession");
|
|
3295
|
+
}
|
|
3296
|
+
}
|
|
3297
|
+
function onArrowKeyDown({ currentInputValue, key }) {
|
|
3298
|
+
const pastMessages = props.pastChatMessages;
|
|
3299
|
+
const isCurrentInputEmptyOrMatch = currentInputValue.length === 0 || pastMessages.includes(currentInputValue);
|
|
3300
|
+
if (isCurrentInputEmptyOrMatch && (key === "ArrowUp" || key === "ArrowDown")) {
|
|
3301
|
+
if (pastMessages.length === 0) return;
|
|
3302
|
+
chatEventBus.emit("blurInput");
|
|
3303
|
+
if (pastMessages.length === 1) {
|
|
3304
|
+
previousMessageIndex.value = 0;
|
|
3305
|
+
} else {
|
|
3306
|
+
if (key === "ArrowUp") {
|
|
3307
|
+
if (currentInputValue.length === 0 && previousMessageIndex.value === 0) {
|
|
3308
|
+
previousMessageIndex.value = pastMessages.length - 1;
|
|
3309
|
+
} else {
|
|
3310
|
+
previousMessageIndex.value = previousMessageIndex.value === 0 ? pastMessages.length - 1 : previousMessageIndex.value - 1;
|
|
3311
|
+
}
|
|
3312
|
+
} else if (key === "ArrowDown") {
|
|
3313
|
+
previousMessageIndex.value = previousMessageIndex.value === pastMessages.length - 1 ? 0 : previousMessageIndex.value + 1;
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
const selectedMessage = pastMessages[previousMessageIndex.value];
|
|
3317
|
+
chatEventBus.emit("setInputValue", selectedMessage);
|
|
3318
|
+
chatEventBus.emit("focusInput");
|
|
3319
|
+
}
|
|
3320
|
+
if (!isCurrentInputEmptyOrMatch) {
|
|
3321
|
+
previousMessageIndex.value = 0;
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
function copySessionId() {
|
|
3325
|
+
void clipboard.copy(props.sessionId);
|
|
3326
|
+
toast.showMessage({
|
|
3327
|
+
title: locale.baseText("generic.copiedToClipboard"),
|
|
3328
|
+
message: "",
|
|
3329
|
+
type: "success"
|
|
3330
|
+
});
|
|
3331
|
+
}
|
|
3332
|
+
return (_ctx, _cache) => {
|
|
3333
|
+
const _component_n8n_tooltip = resolveComponent("n8n-tooltip");
|
|
3334
|
+
const _component_n8n_icon_button = resolveComponent("n8n-icon-button");
|
|
3335
|
+
const _component_n8n_button = resolveComponent("n8n-button");
|
|
3336
|
+
return openBlock(), createElementBlock("div", {
|
|
3337
|
+
class: normalizeClass(_ctx.$style.chat),
|
|
3338
|
+
"data-test-id": "workflow-lm-chat-dialog"
|
|
3339
|
+
}, [
|
|
3340
|
+
createBaseVNode("header", {
|
|
3341
|
+
class: normalizeClass(_ctx.$style.chatHeader)
|
|
3342
|
+
}, [
|
|
3343
|
+
createBaseVNode("span", null, toDisplayString(unref(locale).baseText("chat.window.title")), 1),
|
|
3344
|
+
createBaseVNode("div", {
|
|
3345
|
+
class: normalizeClass(_ctx.$style.session)
|
|
3346
|
+
}, [
|
|
3347
|
+
createBaseVNode("span", null, toDisplayString(unref(locale).baseText("chat.window.session.title")), 1),
|
|
3348
|
+
createVNode(_component_n8n_tooltip, { placement: "left" }, {
|
|
3349
|
+
content: withCtx(() => [
|
|
3350
|
+
createTextVNode(toDisplayString(_ctx.sessionId), 1)
|
|
3351
|
+
]),
|
|
3352
|
+
default: withCtx(() => [
|
|
3353
|
+
createBaseVNode("span", {
|
|
3354
|
+
class: normalizeClass(_ctx.$style.sessionId),
|
|
3355
|
+
"data-test-id": "chat-session-id",
|
|
3356
|
+
onClick: copySessionId
|
|
3357
|
+
}, toDisplayString(_ctx.sessionId), 3)
|
|
3358
|
+
]),
|
|
3359
|
+
_: 1
|
|
3360
|
+
}),
|
|
3361
|
+
createVNode(_component_n8n_icon_button, {
|
|
3362
|
+
class: normalizeClass(_ctx.$style.refreshSession),
|
|
3363
|
+
"data-test-id": "refresh-session-button",
|
|
3364
|
+
type: "tertiary",
|
|
3365
|
+
text: "",
|
|
3366
|
+
size: "mini",
|
|
3367
|
+
icon: "undo",
|
|
3368
|
+
title: unref(locale).baseText("chat.window.session.reset.confirm"),
|
|
3369
|
+
onClick: onRefreshSession
|
|
3370
|
+
}, null, 8, ["class", "title"])
|
|
3371
|
+
], 2)
|
|
3372
|
+
], 2),
|
|
3373
|
+
createBaseVNode("main", {
|
|
3374
|
+
class: normalizeClass(_ctx.$style.chatBody)
|
|
3375
|
+
}, [
|
|
3376
|
+
createVNode(_sfc_main$5, {
|
|
3377
|
+
messages: _ctx.messages,
|
|
3378
|
+
class: normalizeClass([_ctx.$style.messages, "ignore-key-press-canvas"])
|
|
3379
|
+
}, {
|
|
3380
|
+
beforeMessage: withCtx(({ message }) => [
|
|
3381
|
+
message.sender === "bot" && !message.id.includes("preload") ? (openBlock(), createBlock(MessageOptionTooltip, {
|
|
3382
|
+
key: 0,
|
|
3383
|
+
placement: "right",
|
|
3384
|
+
"data-test-id": "execution-id-tooltip"
|
|
3385
|
+
}, {
|
|
3386
|
+
default: withCtx(() => [
|
|
3387
|
+
createTextVNode(toDisplayString(unref(locale).baseText("chat.window.chat.chatMessageOptions.executionId")) + ": ", 1),
|
|
3388
|
+
createBaseVNode("a", {
|
|
3389
|
+
href: "#",
|
|
3390
|
+
onClick: ($event) => emit("displayExecution", message.id)
|
|
3391
|
+
}, toDisplayString(message.id), 9, _hoisted_1$1)
|
|
3392
|
+
]),
|
|
3393
|
+
_: 2
|
|
3394
|
+
}, 1024)) : createCommentVNode("", true),
|
|
3395
|
+
isTextMessage(message) && message.sender === "user" ? (openBlock(), createBlock(MessageOptionAction, {
|
|
3396
|
+
key: 1,
|
|
3397
|
+
"data-test-id": "repost-message-button",
|
|
3398
|
+
icon: "redo",
|
|
3399
|
+
label: unref(locale).baseText("chat.window.chat.chatMessageOptions.repostMessage"),
|
|
3400
|
+
placement: "left",
|
|
3401
|
+
onClickOnce: ($event) => repostMessage(message)
|
|
3402
|
+
}, null, 8, ["label", "onClickOnce"])) : createCommentVNode("", true),
|
|
3403
|
+
isTextMessage(message) && message.sender === "user" ? (openBlock(), createBlock(MessageOptionAction, {
|
|
3404
|
+
key: 2,
|
|
3405
|
+
"data-test-id": "reuse-message-button",
|
|
3406
|
+
icon: "copy",
|
|
3407
|
+
label: unref(locale).baseText("chat.window.chat.chatMessageOptions.reuseMessage"),
|
|
3408
|
+
placement: "left",
|
|
3409
|
+
onClick: ($event) => reuseMessage(message)
|
|
3410
|
+
}, null, 8, ["label", "onClick"])) : createCommentVNode("", true)
|
|
3411
|
+
]),
|
|
3412
|
+
_: 1
|
|
3413
|
+
}, 8, ["messages", "class"])
|
|
3414
|
+
], 2),
|
|
3415
|
+
createBaseVNode("div", {
|
|
3416
|
+
class: normalizeClass(_ctx.$style.messagesInput)
|
|
3417
|
+
}, [
|
|
3418
|
+
_ctx.pastChatMessages.length > 0 ? (openBlock(), createElementBlock("div", {
|
|
3419
|
+
key: 0,
|
|
3420
|
+
class: normalizeClass(_ctx.$style.messagesHistory)
|
|
3421
|
+
}, [
|
|
3422
|
+
createVNode(_component_n8n_button, {
|
|
3423
|
+
title: "Navigate to previous message",
|
|
3424
|
+
icon: "chevron-up",
|
|
3425
|
+
type: "tertiary",
|
|
3426
|
+
text: "",
|
|
3427
|
+
size: "mini",
|
|
3428
|
+
onClick: _cache[0] || (_cache[0] = ($event) => onArrowKeyDown({ currentInputValue: "", key: "ArrowUp" }))
|
|
3429
|
+
}),
|
|
3430
|
+
createVNode(_component_n8n_button, {
|
|
3431
|
+
title: "Navigate to next message",
|
|
3432
|
+
icon: "chevron-down",
|
|
3433
|
+
type: "tertiary",
|
|
3434
|
+
text: "",
|
|
3435
|
+
size: "mini",
|
|
3436
|
+
onClick: _cache[1] || (_cache[1] = ($event) => onArrowKeyDown({ currentInputValue: "", key: "ArrowDown" }))
|
|
3437
|
+
})
|
|
3438
|
+
], 2)) : createCommentVNode("", true),
|
|
3439
|
+
createVNode(ChatInput, {
|
|
3440
|
+
"data-test-id": "lm-chat-inputs",
|
|
3441
|
+
placeholder: inputPlaceholder.value,
|
|
3442
|
+
onArrowKeyDown
|
|
3443
|
+
}, null, 8, ["placeholder"])
|
|
3444
|
+
], 2)
|
|
3445
|
+
], 2);
|
|
3446
|
+
};
|
|
3447
|
+
}
|
|
3448
|
+
});
|
|
3449
|
+
const chat$1 = "_chat_9ze98_1";
|
|
3450
|
+
const chatHeader = "_chatHeader_9ze98_22";
|
|
3451
|
+
const session = "_session_9ze98_35";
|
|
3452
|
+
const sessionId = "_sessionId_9ze98_43";
|
|
3453
|
+
const refreshSession = "_refreshSession_9ze98_51";
|
|
3454
|
+
const chatBody = "_chatBody_9ze98_55";
|
|
3455
|
+
const messages = "_messages_9ze98_61";
|
|
3456
|
+
const messagesInput = "_messagesInput_9ze98_72";
|
|
3457
|
+
const messagesHistory = "_messagesHistory_9ze98_106";
|
|
3458
|
+
const style0$2 = {
|
|
3459
|
+
chat: chat$1,
|
|
3460
|
+
chatHeader,
|
|
3461
|
+
session,
|
|
3462
|
+
sessionId,
|
|
3463
|
+
refreshSession,
|
|
3464
|
+
chatBody,
|
|
3465
|
+
messages,
|
|
3466
|
+
messagesInput,
|
|
3467
|
+
messagesHistory
|
|
3468
|
+
};
|
|
3469
|
+
const cssModules$2 = {
|
|
3470
|
+
"$style": style0$2
|
|
3471
|
+
};
|
|
3472
|
+
const ChatMessagesPanel = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__cssModules", cssModules$2]]);
|
|
3473
|
+
const _hoisted_1 = { class: "meta" };
|
|
3474
|
+
const _hoisted_2 = { key: 0 };
|
|
3475
|
+
const _sfc_main$1 = /* @__PURE__ */ defineComponent({
|
|
3476
|
+
__name: "ChatLogsPanel",
|
|
3477
|
+
props: {
|
|
3478
|
+
node: {},
|
|
3479
|
+
slim: { type: Boolean },
|
|
3480
|
+
workflow: {}
|
|
3481
|
+
},
|
|
3482
|
+
emits: ["close"],
|
|
3483
|
+
setup(__props, { emit: __emit }) {
|
|
3484
|
+
const emit = __emit;
|
|
3485
|
+
const locale = useI18n$1();
|
|
3486
|
+
return (_ctx, _cache) => {
|
|
3487
|
+
const _component_n8n_icon_button = resolveComponent("n8n-icon-button");
|
|
3488
|
+
return openBlock(), createElementBlock("div", {
|
|
3489
|
+
class: normalizeClass(_ctx.$style.logsWrapper),
|
|
3490
|
+
"data-test-id": "lm-chat-logs"
|
|
3491
|
+
}, [
|
|
3492
|
+
createBaseVNode("header", {
|
|
3493
|
+
class: normalizeClass(_ctx.$style.logsHeader)
|
|
3494
|
+
}, [
|
|
3495
|
+
createBaseVNode("div", _hoisted_1, [
|
|
3496
|
+
createTextVNode(toDisplayString(unref(locale).baseText("chat.window.logs")) + " ", 1),
|
|
3497
|
+
_ctx.node ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(unref(locale).baseText("chat.window.logsFromNode", { interpolate: { nodeName: _ctx.node.name } })), 1)) : createCommentVNode("", true)
|
|
3498
|
+
]),
|
|
3499
|
+
createVNode(_component_n8n_icon_button, {
|
|
3500
|
+
class: normalizeClass(_ctx.$style.close),
|
|
3501
|
+
outline: "",
|
|
3502
|
+
icon: "times",
|
|
3503
|
+
type: "secondary",
|
|
3504
|
+
size: "mini",
|
|
3505
|
+
onClick: _cache[0] || (_cache[0] = ($event) => emit("close"))
|
|
3506
|
+
}, null, 8, ["class"])
|
|
3507
|
+
], 2),
|
|
3508
|
+
createBaseVNode("div", {
|
|
3509
|
+
class: normalizeClass(_ctx.$style.logs)
|
|
3510
|
+
}, [
|
|
3511
|
+
_ctx.node ? (openBlock(), createBlock(RunDataAi, {
|
|
3512
|
+
key: 0,
|
|
3513
|
+
class: normalizeClass(_ctx.$style.runData),
|
|
3514
|
+
node: _ctx.node,
|
|
3515
|
+
workflow: _ctx.workflow,
|
|
3516
|
+
slim: _ctx.slim
|
|
3517
|
+
}, null, 8, ["class", "node", "workflow", "slim"])) : createCommentVNode("", true)
|
|
3518
|
+
], 2)
|
|
3519
|
+
], 2);
|
|
3520
|
+
};
|
|
3521
|
+
}
|
|
3522
|
+
});
|
|
3523
|
+
const logsHeader = "_logsHeader_1qrym_1";
|
|
3524
|
+
const close = "_close_1qrym_14";
|
|
3525
|
+
const logsWrapper = "_logsWrapper_1qrym_21";
|
|
3526
|
+
const logsTitle = "_logsTitle_1qrym_30";
|
|
3527
|
+
const logs$1 = "_logs_1qrym_1";
|
|
3528
|
+
const style0$1 = {
|
|
3529
|
+
logsHeader,
|
|
3530
|
+
close,
|
|
3531
|
+
logsWrapper,
|
|
3532
|
+
logsTitle,
|
|
3533
|
+
logs: logs$1
|
|
3534
|
+
};
|
|
3535
|
+
const cssModules$1 = {
|
|
3536
|
+
"$style": style0$1
|
|
3537
|
+
};
|
|
3538
|
+
const ChatLogsPanel = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__cssModules", cssModules$1]]);
|
|
3539
|
+
function useChatTrigger({
|
|
3540
|
+
getNodeByName,
|
|
3541
|
+
getNodeType,
|
|
3542
|
+
canvasNodes,
|
|
3543
|
+
workflow
|
|
3544
|
+
}) {
|
|
3545
|
+
const chatTriggerName = ref(null);
|
|
3546
|
+
const connectedNode = ref(null);
|
|
3547
|
+
const chatTriggerNode = computed(
|
|
3548
|
+
() => chatTriggerName.value ? getNodeByName(chatTriggerName.value) : null
|
|
3549
|
+
);
|
|
3550
|
+
const allowFileUploads = computed(() => {
|
|
3551
|
+
var _a, _b, _c;
|
|
3552
|
+
return ((_c = (_b = (_a = chatTriggerNode.value) == null ? void 0 : _a.parameters) == null ? void 0 : _b.options) == null ? void 0 : _c.allowFileUploads) === true;
|
|
3553
|
+
});
|
|
3554
|
+
const allowedFilesMimeTypes = computed(() => {
|
|
3555
|
+
var _a, _b, _c, _d;
|
|
3556
|
+
return ((_d = (_c = (_b = (_a = chatTriggerNode.value) == null ? void 0 : _a.parameters) == null ? void 0 : _b.options) == null ? void 0 : _c.allowedFilesMimeTypes) == null ? void 0 : _d.toString()) ?? "";
|
|
3557
|
+
});
|
|
3558
|
+
function setChatTriggerNode() {
|
|
3559
|
+
const triggerNode = unref(canvasNodes).find(
|
|
3560
|
+
(node) => [CHAT_TRIGGER_NODE_TYPE, MANUAL_CHAT_TRIGGER_NODE_TYPE].includes(node.type)
|
|
3561
|
+
);
|
|
3562
|
+
if (!triggerNode) {
|
|
3563
|
+
return;
|
|
3564
|
+
}
|
|
3565
|
+
chatTriggerName.value = triggerNode.name;
|
|
3566
|
+
}
|
|
3567
|
+
function setConnectedNode() {
|
|
3568
|
+
const triggerNode = chatTriggerNode.value;
|
|
3569
|
+
if (!triggerNode) {
|
|
3570
|
+
return;
|
|
3571
|
+
}
|
|
3572
|
+
const chatChildren = workflow.value.getChildNodes(triggerNode.name);
|
|
3573
|
+
const chatRootNode = chatChildren.reverse().map((nodeName) => getNodeByName(nodeName)).filter((n) => n !== null).reverse().find((storeNode) => {
|
|
3574
|
+
var _a, _b, _c, _d, _e, _f;
|
|
3575
|
+
if (storeNode.type === CHAIN_SUMMARIZATION_LANGCHAIN_NODE_TYPE) return false;
|
|
3576
|
+
const nodeType = getNodeType(storeNode.type, storeNode.typeVersion);
|
|
3577
|
+
if (!nodeType) return false;
|
|
3578
|
+
const isAgent = (_c = (_b = (_a = nodeType.codex) == null ? void 0 : _a.subcategories) == null ? void 0 : _b[AI_SUBCATEGORY]) == null ? void 0 : _c.includes(AI_CATEGORY_AGENTS);
|
|
3579
|
+
const isChain = (_f = (_e = (_d = nodeType.codex) == null ? void 0 : _d.subcategories) == null ? void 0 : _e[AI_SUBCATEGORY]) == null ? void 0 : _f.includes(AI_CATEGORY_CHAINS);
|
|
3580
|
+
let isCustomChainOrAgent = false;
|
|
3581
|
+
if (nodeType.name === AI_CODE_NODE_TYPE) {
|
|
3582
|
+
const inputs = getNodeInputs(workflow.value, storeNode, nodeType);
|
|
3583
|
+
const inputTypes = getConnectionTypes(inputs);
|
|
3584
|
+
const outputs = getNodeOutputs(workflow.value, storeNode, nodeType);
|
|
3585
|
+
const outputTypes = getConnectionTypes(outputs);
|
|
3586
|
+
if (inputTypes.includes(NodeConnectionType.AiLanguageModel) && inputTypes.includes(NodeConnectionType.Main) && outputTypes.includes(NodeConnectionType.Main)) {
|
|
3587
|
+
isCustomChainOrAgent = true;
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
if (!isAgent && !isChain && !isCustomChainOrAgent) return false;
|
|
3591
|
+
const parentNodes = workflow.value.getParentNodes(storeNode.name);
|
|
3592
|
+
const isChatChild = parentNodes.some(
|
|
3593
|
+
(parentNodeName) => parentNodeName === triggerNode.name
|
|
3594
|
+
);
|
|
3595
|
+
const result = Boolean(isChatChild && (isAgent || isChain || isCustomChainOrAgent));
|
|
3596
|
+
return result;
|
|
3597
|
+
});
|
|
3598
|
+
connectedNode.value = chatRootNode ?? null;
|
|
3599
|
+
}
|
|
3600
|
+
return {
|
|
3601
|
+
allowFileUploads,
|
|
3602
|
+
allowedFilesMimeTypes,
|
|
3603
|
+
chatTriggerNode,
|
|
3604
|
+
connectedNode: computed(() => connectedNode.value),
|
|
3605
|
+
setChatTriggerNode,
|
|
3606
|
+
setConnectedNode
|
|
3607
|
+
};
|
|
3608
|
+
}
|
|
3609
|
+
function useChatMessaging({
|
|
3610
|
+
chatTrigger,
|
|
3611
|
+
connectedNode,
|
|
3612
|
+
messages: messages2,
|
|
3613
|
+
sessionId: sessionId2,
|
|
3614
|
+
workflow,
|
|
3615
|
+
isLoading,
|
|
3616
|
+
executionResultData,
|
|
3617
|
+
getWorkflowResultDataByNodeName,
|
|
3618
|
+
onRunChatWorkflow
|
|
3619
|
+
}) {
|
|
3620
|
+
const locale = useI18n$1();
|
|
3621
|
+
const { showError } = useToast();
|
|
3622
|
+
const previousMessageIndex = ref(0);
|
|
3623
|
+
async function convertFileToBinaryData(file) {
|
|
3624
|
+
const reader = new FileReader();
|
|
3625
|
+
return await new Promise((resolve, reject) => {
|
|
3626
|
+
reader.onload = () => {
|
|
3627
|
+
var _a;
|
|
3628
|
+
const binaryData = {
|
|
3629
|
+
data: ((_a = reader.result.split("base64,")) == null ? void 0 : _a[1]) ?? "",
|
|
3630
|
+
mimeType: file.type,
|
|
3631
|
+
fileName: file.name,
|
|
3632
|
+
fileSize: `${file.size} bytes`,
|
|
3633
|
+
fileExtension: file.name.split(".").pop() ?? "",
|
|
3634
|
+
fileType: file.type.split("/")[0]
|
|
3635
|
+
};
|
|
3636
|
+
resolve(binaryData);
|
|
3637
|
+
};
|
|
3638
|
+
reader.onerror = () => {
|
|
3639
|
+
reject(new Error("Failed to convert file to binary data"));
|
|
3640
|
+
};
|
|
3641
|
+
reader.readAsDataURL(file);
|
|
3642
|
+
});
|
|
3643
|
+
}
|
|
3644
|
+
async function getKeyedFiles(files) {
|
|
3645
|
+
const binaryData = {};
|
|
3646
|
+
await Promise.all(
|
|
3647
|
+
files.map(async (file, index) => {
|
|
3648
|
+
const data = await convertFileToBinaryData(file);
|
|
3649
|
+
const key = `data${index}`;
|
|
3650
|
+
binaryData[key] = data;
|
|
3651
|
+
})
|
|
3652
|
+
);
|
|
3653
|
+
return binaryData;
|
|
3654
|
+
}
|
|
3655
|
+
function extractFileMeta(file) {
|
|
3656
|
+
return {
|
|
3657
|
+
fileName: file.name,
|
|
3658
|
+
fileSize: `${file.size} bytes`,
|
|
3659
|
+
fileExtension: file.name.split(".").pop() ?? "",
|
|
3660
|
+
fileType: file.type.split("/")[0],
|
|
3661
|
+
mimeType: file.type
|
|
3662
|
+
};
|
|
3663
|
+
}
|
|
3664
|
+
async function startWorkflowWithMessage(message, files) {
|
|
3665
|
+
const triggerNode = chatTrigger.value;
|
|
3666
|
+
if (!triggerNode) {
|
|
3667
|
+
showError(new Error("Chat Trigger Node could not be found!"), "Trigger Node not found");
|
|
3668
|
+
return;
|
|
3669
|
+
}
|
|
3670
|
+
let inputKey = "chatInput";
|
|
3671
|
+
if (triggerNode.type === MANUAL_CHAT_TRIGGER_NODE_TYPE && triggerNode.typeVersion < 1.1) {
|
|
3672
|
+
inputKey = "input";
|
|
3673
|
+
}
|
|
3674
|
+
if (triggerNode.type === CHAT_TRIGGER_NODE_TYPE$1) {
|
|
3675
|
+
inputKey = "chatInput";
|
|
3676
|
+
}
|
|
3677
|
+
const inputPayload = {
|
|
3678
|
+
json: {
|
|
3679
|
+
sessionId: sessionId2.value,
|
|
3680
|
+
action: "sendMessage",
|
|
3681
|
+
[inputKey]: message
|
|
3682
|
+
}
|
|
3683
|
+
};
|
|
3684
|
+
if (files && files.length > 0) {
|
|
3685
|
+
const filesMeta = files.map((file) => extractFileMeta(file));
|
|
3686
|
+
const binaryData = await getKeyedFiles(files);
|
|
3687
|
+
inputPayload.json.files = filesMeta;
|
|
3688
|
+
inputPayload.binary = binaryData;
|
|
3689
|
+
}
|
|
3690
|
+
const nodeData = {
|
|
3691
|
+
startTime: (/* @__PURE__ */ new Date()).getTime(),
|
|
3692
|
+
executionTime: 0,
|
|
3693
|
+
executionStatus: "success",
|
|
3694
|
+
data: {
|
|
3695
|
+
main: [[inputPayload]]
|
|
3696
|
+
},
|
|
3697
|
+
source: [null]
|
|
3698
|
+
};
|
|
3699
|
+
const response = await onRunChatWorkflow({
|
|
3700
|
+
triggerNode: triggerNode.name,
|
|
3701
|
+
nodeData,
|
|
3702
|
+
source: "RunData.ManualChatMessage",
|
|
3703
|
+
message
|
|
3704
|
+
});
|
|
3705
|
+
if (!(response == null ? void 0 : response.executionId)) {
|
|
3706
|
+
showError(
|
|
3707
|
+
new Error("It was not possible to start workflow!"),
|
|
3708
|
+
"Workflow could not be started"
|
|
3709
|
+
);
|
|
3710
|
+
return;
|
|
3711
|
+
}
|
|
3712
|
+
waitForExecution(response.executionId);
|
|
3713
|
+
}
|
|
3714
|
+
function waitForExecution(executionId) {
|
|
3715
|
+
const waitInterval = setInterval(() => {
|
|
3716
|
+
var _a;
|
|
3717
|
+
if (!isLoading.value) {
|
|
3718
|
+
clearInterval(waitInterval);
|
|
3719
|
+
const lastNodeExecuted = (_a = executionResultData.value) == null ? void 0 : _a.lastNodeExecuted;
|
|
3720
|
+
if (!lastNodeExecuted) return;
|
|
3721
|
+
const nodeResponseDataArray = get(executionResultData.value.runData, lastNodeExecuted) ?? [];
|
|
3722
|
+
const nodeResponseData = nodeResponseDataArray[nodeResponseDataArray.length - 1];
|
|
3723
|
+
let responseMessage;
|
|
3724
|
+
if (get(nodeResponseData, "error")) {
|
|
3725
|
+
responseMessage = "[ERROR: " + get(nodeResponseData, "error.message") + "]";
|
|
3726
|
+
} else {
|
|
3727
|
+
const responseData = get(nodeResponseData, "data.main[0][0].json");
|
|
3728
|
+
responseMessage = extractResponseMessage(responseData);
|
|
3729
|
+
}
|
|
3730
|
+
messages2.value.push({
|
|
3731
|
+
text: responseMessage,
|
|
3732
|
+
sender: "bot",
|
|
3733
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3734
|
+
id: executionId ?? v4()
|
|
3735
|
+
});
|
|
3736
|
+
}
|
|
3737
|
+
}, 500);
|
|
3738
|
+
}
|
|
3739
|
+
function extractResponseMessage(responseData) {
|
|
3740
|
+
if (!responseData || isEmpty(responseData)) {
|
|
3741
|
+
return locale.baseText("chat.window.chat.response.empty");
|
|
3742
|
+
}
|
|
3743
|
+
const paths = ["output", "text", "response.text"];
|
|
3744
|
+
const matchedPath = paths.find((path) => get(responseData, path));
|
|
3745
|
+
if (!matchedPath) return JSON.stringify(responseData, null, 2);
|
|
3746
|
+
const matchedOutput = get(responseData, matchedPath);
|
|
3747
|
+
if (typeof matchedOutput === "object") {
|
|
3748
|
+
return "```json\n" + JSON.stringify(matchedOutput, null, 2) + "\n```";
|
|
3749
|
+
}
|
|
3750
|
+
return (matchedOutput == null ? void 0 : matchedOutput.toString()) ?? "";
|
|
3751
|
+
}
|
|
3752
|
+
async function sendMessage(message, files) {
|
|
3753
|
+
previousMessageIndex.value = 0;
|
|
3754
|
+
if (message.trim() === "" && (!files || files.length === 0)) {
|
|
3755
|
+
showError(
|
|
3756
|
+
new Error(locale.baseText("chat.window.chat.provideMessage")),
|
|
3757
|
+
locale.baseText("chat.window.chat.emptyChatMessage")
|
|
3758
|
+
);
|
|
3759
|
+
return;
|
|
3760
|
+
}
|
|
3761
|
+
const pinnedChatData = usePinnedData(chatTrigger.value);
|
|
3762
|
+
if (pinnedChatData.hasData.value) {
|
|
3763
|
+
const confirmResult = await useMessage().confirm(
|
|
3764
|
+
locale.baseText("chat.window.chat.unpinAndExecute.description"),
|
|
3765
|
+
locale.baseText("chat.window.chat.unpinAndExecute.title"),
|
|
3766
|
+
{
|
|
3767
|
+
confirmButtonText: locale.baseText("chat.window.chat.unpinAndExecute.confirm"),
|
|
3768
|
+
cancelButtonText: locale.baseText("chat.window.chat.unpinAndExecute.cancel")
|
|
3769
|
+
}
|
|
3770
|
+
);
|
|
3771
|
+
if (!(confirmResult === MODAL_CONFIRM)) return;
|
|
3772
|
+
pinnedChatData.unsetData("unpin-and-send-chat-message-modal");
|
|
3773
|
+
}
|
|
3774
|
+
const newMessage = {
|
|
3775
|
+
text: message,
|
|
3776
|
+
sender: "user",
|
|
3777
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3778
|
+
sessionId: sessionId2.value,
|
|
3779
|
+
id: v4(),
|
|
3780
|
+
files
|
|
3781
|
+
};
|
|
3782
|
+
messages2.value.push(newMessage);
|
|
3783
|
+
await startWorkflowWithMessage(newMessage.text, files);
|
|
3784
|
+
}
|
|
3785
|
+
function getChatMessages() {
|
|
3786
|
+
var _a, _b, _c;
|
|
3787
|
+
if (!connectedNode.value) return [];
|
|
3788
|
+
const connectedMemoryInputs = (_b = (_a = workflow.value.connectionsByDestinationNode) == null ? void 0 : _a[connectedNode.value.name]) == null ? void 0 : _b[NodeConnectionType.AiMemory];
|
|
3789
|
+
if (!connectedMemoryInputs) return [];
|
|
3790
|
+
const memoryConnection = (_c = (connectedMemoryInputs ?? []).find((i) => i.length > 0)) == null ? void 0 : _c[0];
|
|
3791
|
+
if (!memoryConnection) return [];
|
|
3792
|
+
const nodeResultData = getWorkflowResultDataByNodeName(memoryConnection.node);
|
|
3793
|
+
const memoryOutputData = (nodeResultData ?? []).map((data) => get(data, ["data", NodeConnectionType.AiMemory, 0, 0, "json"])).find((data) => data && data.action === "saveContext");
|
|
3794
|
+
return ((memoryOutputData == null ? void 0 : memoryOutputData.chatHistory) ?? []).map((message, index) => {
|
|
3795
|
+
return {
|
|
3796
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3797
|
+
text: message.kwargs.content,
|
|
3798
|
+
id: `preload__${index}`,
|
|
3799
|
+
sender: last(message.id) === "HumanMessage" ? "user" : "bot"
|
|
3800
|
+
};
|
|
3801
|
+
});
|
|
3802
|
+
}
|
|
3803
|
+
return {
|
|
3804
|
+
previousMessageIndex,
|
|
3805
|
+
sendMessage,
|
|
3806
|
+
extractResponseMessage,
|
|
3807
|
+
waitForExecution,
|
|
3808
|
+
getChatMessages
|
|
3809
|
+
};
|
|
3810
|
+
}
|
|
3811
|
+
const LOCAL_STORAGE_PANEL_HEIGHT = "N8N_CANVAS_CHAT_HEIGHT";
|
|
3812
|
+
const LOCAL_STORAGE_PANEL_WIDTH = "N8N_CANVAS_CHAT_WIDTH";
|
|
3813
|
+
const MAX_WIDTH_PERCENTAGE = 0.8;
|
|
3814
|
+
const MIN_WIDTH_PERCENTAGE = 0.3;
|
|
3815
|
+
const MIN_HEIGHT_PERCENTAGE = 0.3;
|
|
3816
|
+
const MAX_HEIGHT_PERCENTAGE = 0.75;
|
|
3817
|
+
function useResize(container2) {
|
|
3818
|
+
const storage = {
|
|
3819
|
+
height: useStorage(LOCAL_STORAGE_PANEL_HEIGHT),
|
|
3820
|
+
width: useStorage(LOCAL_STORAGE_PANEL_WIDTH)
|
|
3821
|
+
};
|
|
3822
|
+
const dimensions = {
|
|
3823
|
+
container: ref(0),
|
|
3824
|
+
// Container width
|
|
3825
|
+
minHeight: ref(0),
|
|
3826
|
+
maxHeight: ref(0),
|
|
3827
|
+
chat: ref(0),
|
|
3828
|
+
// Chat panel width
|
|
3829
|
+
logs: ref(0),
|
|
3830
|
+
height: ref(0)
|
|
3831
|
+
};
|
|
3832
|
+
const rootStyles = computed(() => ({
|
|
3833
|
+
"--panel-height": `${dimensions.height.value}px`,
|
|
3834
|
+
"--chat-width": `${dimensions.chat.value}px`
|
|
3835
|
+
}));
|
|
3836
|
+
const panelToContainerRatio = computed(() => {
|
|
3837
|
+
const chatRatio = dimensions.chat.value / dimensions.container.value;
|
|
3838
|
+
const containerRatio = dimensions.container.value / window.screen.width;
|
|
3839
|
+
return {
|
|
3840
|
+
chat: chatRatio.toFixed(2),
|
|
3841
|
+
logs: (1 - chatRatio).toFixed(2),
|
|
3842
|
+
container: containerRatio.toFixed(2)
|
|
3843
|
+
};
|
|
3844
|
+
});
|
|
3845
|
+
function onResize(newHeight) {
|
|
3846
|
+
const { minHeight, maxHeight } = dimensions;
|
|
3847
|
+
dimensions.height.value = Math.min(Math.max(newHeight, minHeight.value), maxHeight.value);
|
|
3848
|
+
}
|
|
3849
|
+
function onResizeDebounced(data) {
|
|
3850
|
+
void useDebounce().callDebounced(onResize, { debounceTime: 10, trailing: true }, data.height);
|
|
3851
|
+
}
|
|
3852
|
+
function onResizeChat(width) {
|
|
3853
|
+
const containerWidth = dimensions.container.value;
|
|
3854
|
+
const maxWidth = containerWidth * MAX_WIDTH_PERCENTAGE;
|
|
3855
|
+
const minWidth = containerWidth * MIN_WIDTH_PERCENTAGE;
|
|
3856
|
+
dimensions.chat.value = Math.min(Math.max(width, minWidth), maxWidth);
|
|
3857
|
+
dimensions.logs.value = dimensions.container.value - dimensions.chat.value;
|
|
3858
|
+
}
|
|
3859
|
+
function onResizeChatDebounced(data) {
|
|
3860
|
+
void useDebounce().callDebounced(
|
|
3861
|
+
onResizeChat,
|
|
3862
|
+
{ debounceTime: 10, trailing: true },
|
|
3863
|
+
data.width
|
|
3864
|
+
);
|
|
3865
|
+
}
|
|
3866
|
+
function restorePersistedDimensions() {
|
|
3867
|
+
const persistedHeight = parseInt(storage.height.value ?? "0", 10);
|
|
3868
|
+
const persistedWidth = parseInt(storage.width.value ?? "0", 10);
|
|
3869
|
+
if (persistedHeight) onResize(persistedHeight);
|
|
3870
|
+
if (persistedWidth) onResizeChat(persistedWidth);
|
|
3871
|
+
}
|
|
3872
|
+
function onWindowResize() {
|
|
3873
|
+
if (!container2.value) return;
|
|
3874
|
+
dimensions.container.value = container2.value.getBoundingClientRect().width;
|
|
3875
|
+
onResizeChat(dimensions.chat.value);
|
|
3876
|
+
dimensions.minHeight.value = window.innerHeight * MIN_HEIGHT_PERCENTAGE;
|
|
3877
|
+
dimensions.maxHeight.value = window.innerHeight * MAX_HEIGHT_PERCENTAGE;
|
|
3878
|
+
onResize(dimensions.height.value);
|
|
3879
|
+
}
|
|
3880
|
+
watchEffect(() => {
|
|
3881
|
+
const { chat: chat2, height } = dimensions;
|
|
3882
|
+
if (chat2.value > 0) storage.width.value = chat2.value.toString();
|
|
3883
|
+
if (height.value > 0) storage.height.value = height.value.toString();
|
|
3884
|
+
});
|
|
3885
|
+
watchEffect(() => {
|
|
3886
|
+
if (container2.value) {
|
|
3887
|
+
onWindowResize();
|
|
3888
|
+
restorePersistedDimensions();
|
|
3889
|
+
}
|
|
3890
|
+
});
|
|
3891
|
+
onMounted(() => window.addEventListener("resize", onWindowResize));
|
|
3892
|
+
onBeforeUnmount(() => window.removeEventListener("resize", onWindowResize));
|
|
3893
|
+
return {
|
|
3894
|
+
height: dimensions.height,
|
|
3895
|
+
chatWidth: dimensions.chat,
|
|
3896
|
+
logsWidth: dimensions.logs,
|
|
3897
|
+
rootStyles,
|
|
3898
|
+
onWindowResize,
|
|
3899
|
+
onResizeDebounced,
|
|
3900
|
+
onResizeChatDebounced,
|
|
3901
|
+
panelToContainerRatio
|
|
3902
|
+
};
|
|
3903
|
+
}
|
|
3904
|
+
const _sfc_main = /* @__PURE__ */ defineComponent({
|
|
3905
|
+
__name: "CanvasChat",
|
|
3906
|
+
setup(__props, { expose: __expose }) {
|
|
3907
|
+
const workflowsStore = useWorkflowsStore();
|
|
3908
|
+
const uiStore = useUIStore();
|
|
3909
|
+
const canvasStore = useCanvasStore();
|
|
3910
|
+
const nodeTypesStore = useNodeTypesStore();
|
|
3911
|
+
const nodeHelpers = useNodeHelpers();
|
|
3912
|
+
const router = useRouter();
|
|
3913
|
+
const messages2 = ref([]);
|
|
3914
|
+
const currentSessionId = ref(v4().replace(/-/g, ""));
|
|
3915
|
+
const isDisabled = ref(false);
|
|
3916
|
+
const container2 = ref();
|
|
3917
|
+
const workflow = computed(() => workflowsStore.getCurrentWorkflow());
|
|
3918
|
+
const isLoading = computed(() => {
|
|
3919
|
+
const result = uiStore.isActionActive.workflowRunning;
|
|
3920
|
+
return result;
|
|
3921
|
+
});
|
|
3922
|
+
const allConnections = computed(() => workflowsStore.allConnections);
|
|
3923
|
+
const isChatOpen = computed(() => {
|
|
3924
|
+
const result = workflowsStore.isChatPanelOpen;
|
|
3925
|
+
return result;
|
|
3926
|
+
});
|
|
3927
|
+
const canvasNodes = computed(() => workflowsStore.allNodes);
|
|
3928
|
+
const isLogsOpen = computed(() => workflowsStore.isLogsPanelOpen);
|
|
3929
|
+
const previousChatMessages = computed(() => workflowsStore.getPastChatMessages);
|
|
3930
|
+
__expose({
|
|
3931
|
+
messages: messages2,
|
|
3932
|
+
currentSessionId,
|
|
3933
|
+
isDisabled,
|
|
3934
|
+
workflow,
|
|
3935
|
+
isLoading
|
|
3936
|
+
});
|
|
3937
|
+
const { runWorkflow } = useRunWorkflow({ router });
|
|
3938
|
+
const { chatTriggerNode, connectedNode, allowFileUploads, setChatTriggerNode, setConnectedNode } = useChatTrigger({
|
|
3939
|
+
workflow,
|
|
3940
|
+
canvasNodes,
|
|
3941
|
+
getNodeByName: workflowsStore.getNodeByName,
|
|
3942
|
+
getNodeType: nodeTypesStore.getNodeType
|
|
3943
|
+
});
|
|
3944
|
+
const { sendMessage, getChatMessages } = useChatMessaging({
|
|
3945
|
+
chatTrigger: chatTriggerNode,
|
|
3946
|
+
connectedNode,
|
|
3947
|
+
messages: messages2,
|
|
3948
|
+
sessionId: currentSessionId,
|
|
3949
|
+
workflow,
|
|
3950
|
+
isLoading,
|
|
3951
|
+
executionResultData: computed(() => {
|
|
3952
|
+
var _a, _b;
|
|
3953
|
+
return (_b = (_a = workflowsStore.getWorkflowExecution) == null ? void 0 : _a.data) == null ? void 0 : _b.resultData;
|
|
3954
|
+
}),
|
|
3955
|
+
getWorkflowResultDataByNodeName: workflowsStore.getWorkflowResultDataByNodeName,
|
|
3956
|
+
onRunChatWorkflow
|
|
3957
|
+
});
|
|
3958
|
+
const {
|
|
3959
|
+
height,
|
|
3960
|
+
chatWidth,
|
|
3961
|
+
rootStyles,
|
|
3962
|
+
logsWidth,
|
|
3963
|
+
onResizeDebounced,
|
|
3964
|
+
onResizeChatDebounced,
|
|
3965
|
+
onWindowResize
|
|
3966
|
+
} = useResize(container2);
|
|
3967
|
+
function createChatConfig(params) {
|
|
3968
|
+
const chatConfig2 = {
|
|
3969
|
+
messages: params.messages,
|
|
3970
|
+
sendMessage: params.sendMessage,
|
|
3971
|
+
initialMessages: ref([]),
|
|
3972
|
+
currentSessionId: params.currentSessionId,
|
|
3973
|
+
waitingForResponse: params.isLoading
|
|
3974
|
+
};
|
|
3975
|
+
const chatOptions2 = {
|
|
3976
|
+
i18n: {
|
|
3977
|
+
en: {
|
|
3978
|
+
title: "",
|
|
3979
|
+
footer: "",
|
|
3980
|
+
subtitle: "",
|
|
3981
|
+
inputPlaceholder: params.locale.baseText("chat.window.chat.placeholder"),
|
|
3982
|
+
getStarted: "",
|
|
3983
|
+
closeButtonTooltip: ""
|
|
3984
|
+
}
|
|
3985
|
+
},
|
|
3986
|
+
webhookUrl: "",
|
|
3987
|
+
mode: "window",
|
|
3988
|
+
showWindowCloseButton: true,
|
|
3989
|
+
disabled: params.isDisabled,
|
|
3990
|
+
allowFileUploads: params.allowFileUploads,
|
|
3991
|
+
allowedFilesMimeTypes: ""
|
|
3992
|
+
};
|
|
3993
|
+
return { chatConfig: chatConfig2, chatOptions: chatOptions2 };
|
|
3994
|
+
}
|
|
3995
|
+
function displayExecution(params) {
|
|
3996
|
+
const route = params.router.resolve({
|
|
3997
|
+
name: VIEWS.EXECUTION_PREVIEW,
|
|
3998
|
+
params: { name: params.workflowId, executionId: params.executionId }
|
|
3999
|
+
});
|
|
4000
|
+
window.open(route.href, "_blank");
|
|
4001
|
+
}
|
|
4002
|
+
function refreshSession2(params) {
|
|
4003
|
+
workflowsStore.setWorkflowExecutionData(null);
|
|
4004
|
+
nodeHelpers.updateNodesExecutionIssues();
|
|
4005
|
+
params.messages.value = [];
|
|
4006
|
+
params.currentSessionId.value = v4().replace(/-/g, "");
|
|
4007
|
+
}
|
|
4008
|
+
const handleDisplayExecution = (executionId) => {
|
|
4009
|
+
displayExecution({
|
|
4010
|
+
router,
|
|
4011
|
+
workflowId: workflow.value.id,
|
|
4012
|
+
executionId
|
|
4013
|
+
});
|
|
4014
|
+
};
|
|
4015
|
+
const handleRefreshSession = () => {
|
|
4016
|
+
refreshSession2({
|
|
4017
|
+
messages: messages2,
|
|
4018
|
+
currentSessionId
|
|
4019
|
+
});
|
|
4020
|
+
};
|
|
4021
|
+
const closePanel = () => {
|
|
4022
|
+
workflowsStore.setPanelOpen("chat", false);
|
|
4023
|
+
};
|
|
4024
|
+
async function onRunChatWorkflow(payload) {
|
|
4025
|
+
const response = await runWorkflow({
|
|
4026
|
+
triggerNode: payload.triggerNode,
|
|
4027
|
+
nodeData: payload.nodeData,
|
|
4028
|
+
source: payload.source
|
|
4029
|
+
});
|
|
4030
|
+
workflowsStore.appendChatMessage(payload.message);
|
|
4031
|
+
return response;
|
|
4032
|
+
}
|
|
4033
|
+
const { chatConfig, chatOptions } = createChatConfig({
|
|
4034
|
+
messages: messages2,
|
|
4035
|
+
sendMessage,
|
|
4036
|
+
currentSessionId,
|
|
4037
|
+
isLoading,
|
|
4038
|
+
isDisabled,
|
|
4039
|
+
allowFileUploads,
|
|
4040
|
+
locale: useI18n$1()
|
|
4041
|
+
});
|
|
4042
|
+
provide(ChatSymbol, chatConfig);
|
|
4043
|
+
provide(ChatOptionsSymbol, chatOptions);
|
|
4044
|
+
watch(
|
|
4045
|
+
() => isChatOpen.value,
|
|
4046
|
+
(isOpen) => {
|
|
4047
|
+
if (isOpen) {
|
|
4048
|
+
setChatTriggerNode();
|
|
4049
|
+
setConnectedNode();
|
|
4050
|
+
if (messages2.value.length === 0) {
|
|
4051
|
+
messages2.value = getChatMessages();
|
|
4052
|
+
}
|
|
4053
|
+
setTimeout(() => {
|
|
4054
|
+
onWindowResize();
|
|
4055
|
+
chatEventBus.emit("focusInput");
|
|
4056
|
+
}, 0);
|
|
4057
|
+
}
|
|
4058
|
+
},
|
|
4059
|
+
{ immediate: true }
|
|
4060
|
+
);
|
|
4061
|
+
watch(
|
|
4062
|
+
() => allConnections.value,
|
|
4063
|
+
() => {
|
|
4064
|
+
if (canvasStore.isLoading) return;
|
|
4065
|
+
setTimeout(() => {
|
|
4066
|
+
if (!chatTriggerNode.value) {
|
|
4067
|
+
setChatTriggerNode();
|
|
4068
|
+
}
|
|
4069
|
+
setConnectedNode();
|
|
4070
|
+
}, 0);
|
|
4071
|
+
},
|
|
4072
|
+
{ deep: true }
|
|
4073
|
+
);
|
|
4074
|
+
watchEffect(() => {
|
|
4075
|
+
canvasStore.setPanelHeight(isChatOpen.value || isLogsOpen.value ? height.value : 0);
|
|
4076
|
+
});
|
|
4077
|
+
return (_ctx, _cache) => {
|
|
4078
|
+
const _component_n8n_resize_wrapper = resolveComponent("n8n-resize-wrapper");
|
|
4079
|
+
return unref(chatTriggerNode) ? (openBlock(), createBlock(_component_n8n_resize_wrapper, {
|
|
4080
|
+
key: 0,
|
|
4081
|
+
"is-resizing-enabled": isChatOpen.value || isLogsOpen.value,
|
|
4082
|
+
"supported-directions": ["top"],
|
|
4083
|
+
class: normalizeClass([_ctx.$style.resizeWrapper, !isChatOpen.value && !isLogsOpen.value && _ctx.$style.empty]),
|
|
4084
|
+
height: unref(height),
|
|
4085
|
+
style: normalizeStyle(unref(rootStyles)),
|
|
4086
|
+
onResize: unref(onResizeDebounced)
|
|
4087
|
+
}, {
|
|
4088
|
+
default: withCtx(() => [
|
|
4089
|
+
createBaseVNode("div", {
|
|
4090
|
+
ref_key: "container",
|
|
4091
|
+
ref: container2,
|
|
4092
|
+
class: normalizeClass(_ctx.$style.container)
|
|
4093
|
+
}, [
|
|
4094
|
+
isChatOpen.value || isLogsOpen.value ? (openBlock(), createElementBlock("div", {
|
|
4095
|
+
key: 0,
|
|
4096
|
+
class: normalizeClass(_ctx.$style.chatResizer)
|
|
4097
|
+
}, [
|
|
4098
|
+
isChatOpen.value ? (openBlock(), createBlock(_component_n8n_resize_wrapper, {
|
|
4099
|
+
key: 0,
|
|
4100
|
+
"supported-directions": ["right"],
|
|
4101
|
+
width: unref(chatWidth),
|
|
4102
|
+
class: normalizeClass(_ctx.$style.chat),
|
|
4103
|
+
onResize: unref(onResizeChatDebounced)
|
|
4104
|
+
}, {
|
|
4105
|
+
default: withCtx(() => [
|
|
4106
|
+
createBaseVNode("div", {
|
|
4107
|
+
class: normalizeClass(_ctx.$style.inner)
|
|
4108
|
+
}, [
|
|
4109
|
+
createVNode(ChatMessagesPanel, {
|
|
4110
|
+
"data-test-id": "canvas-chat",
|
|
4111
|
+
messages: messages2.value,
|
|
4112
|
+
"session-id": currentSessionId.value,
|
|
4113
|
+
"past-chat-messages": previousChatMessages.value,
|
|
4114
|
+
onRefreshSession: handleRefreshSession,
|
|
4115
|
+
onDisplayExecution: handleDisplayExecution,
|
|
4116
|
+
onSendMessage: unref(sendMessage)
|
|
4117
|
+
}, null, 8, ["messages", "session-id", "past-chat-messages", "onSendMessage"])
|
|
4118
|
+
], 2)
|
|
4119
|
+
]),
|
|
4120
|
+
_: 1
|
|
4121
|
+
}, 8, ["width", "class", "onResize"])) : createCommentVNode("", true),
|
|
4122
|
+
isLogsOpen.value && unref(connectedNode) ? (openBlock(), createElementBlock("div", {
|
|
4123
|
+
key: 1,
|
|
4124
|
+
class: normalizeClass(_ctx.$style.logs)
|
|
4125
|
+
}, [
|
|
4126
|
+
(openBlock(), createBlock(ChatLogsPanel, {
|
|
4127
|
+
key: messages2.value.length,
|
|
4128
|
+
workflow: workflow.value,
|
|
4129
|
+
"data-test-id": "canvas-chat-logs",
|
|
4130
|
+
node: unref(connectedNode),
|
|
4131
|
+
slim: unref(logsWidth) < 700,
|
|
4132
|
+
onClose: closePanel
|
|
4133
|
+
}, null, 8, ["workflow", "node", "slim"]))
|
|
4134
|
+
], 2)) : createCommentVNode("", true)
|
|
4135
|
+
], 2)) : createCommentVNode("", true)
|
|
4136
|
+
], 2)
|
|
4137
|
+
]),
|
|
4138
|
+
_: 1
|
|
4139
|
+
}, 8, ["is-resizing-enabled", "class", "height", "style", "onResize"])) : createCommentVNode("", true);
|
|
4140
|
+
};
|
|
4141
|
+
}
|
|
4142
|
+
});
|
|
4143
|
+
const resizeWrapper = "_resizeWrapper_gmykl_1";
|
|
4144
|
+
const empty = "_empty_gmykl_8";
|
|
4145
|
+
const container = "_container_gmykl_14";
|
|
4146
|
+
const chatResizer = "_chatResizer_gmykl_22";
|
|
4147
|
+
const footer = "_footer_gmykl_29";
|
|
4148
|
+
const chat = "_chat_gmykl_22";
|
|
4149
|
+
const inner = "_inner_gmykl_48";
|
|
4150
|
+
const logs = "_logs_gmykl_56";
|
|
4151
|
+
const style0 = {
|
|
4152
|
+
resizeWrapper,
|
|
4153
|
+
empty,
|
|
4154
|
+
container,
|
|
4155
|
+
chatResizer,
|
|
4156
|
+
footer,
|
|
4157
|
+
chat,
|
|
4158
|
+
inner,
|
|
4159
|
+
logs
|
|
4160
|
+
};
|
|
4161
|
+
const cssModules = {
|
|
4162
|
+
"$style": style0
|
|
4163
|
+
};
|
|
4164
|
+
const CanvasChat = /* @__PURE__ */ _export_sfc(_sfc_main, [["__cssModules", cssModules]]);
|
|
4165
|
+
export {
|
|
4166
|
+
CanvasChat as default
|
|
4167
|
+
};
|