@becrafter/prompt-manager 0.1.11 → 0.1.14
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/env.example +1 -1
- package/examples/prompts/developer/code-review.yaml +32 -0
- package/examples/prompts/developer/code_refactoring.yaml +31 -0
- package/examples/prompts/developer/doc-generator.yaml +36 -0
- package/examples/prompts/developer/error-code-fixer.yaml +35 -0
- package/examples/prompts/engineer/engineer-professional.yaml +92 -0
- package/examples/prompts/engineer/laowang-engineer.yaml +132 -0
- package/examples/prompts/engineer/nekomata-engineer.yaml +123 -0
- package/examples/prompts/engineer/ojousama-engineer.yaml +124 -0
- package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +117 -0
- package/examples/prompts/generator/gen_3d_webpage_html.yaml +75 -0
- package/examples/prompts/generator/gen_bento_grid_html.yaml +112 -0
- package/examples/prompts/generator/gen_html_web_page.yaml +88 -0
- package/examples/prompts/generator/gen_knowledge_card_html.yaml +83 -0
- package/examples/prompts/generator/gen_magazine_card_html.yaml +82 -0
- package/examples/prompts/generator/gen_mimeng_headline_title.yaml +71 -0
- package/examples/prompts/generator/gen_podcast_script.yaml +69 -0
- package/examples/prompts/generator/gen_prd_prototype_html.yaml +175 -0
- package/examples/prompts/generator/gen_summarize.yaml +157 -0
- package/examples/prompts/generator/gen_title.yaml +119 -0
- package/examples/prompts/generator/others/api_documentation.yaml +32 -0
- package/examples/prompts/generator/others/build_mcp_server.yaml +26 -0
- package/examples/prompts/generator/others/project_architecture.yaml +31 -0
- package/examples/prompts/generator/others/test_case_generator.yaml +30 -0
- package/examples/prompts/generator/others/writing_assistant.yaml +72 -0
- package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +105 -0
- package/examples/prompts/workflow/sixstep-workflow.yaml +192 -0
- package/package.json +3 -2
- package/packages/server/app.js +13 -3
- package/packages/server/utils/config.js +1 -1
- package/packages/server/utils/util.js +7 -7
- package/packages/web/0.d1c5a72339dfc32ad86a.js +1 -0
- package/packages/web/112.8807b976372b2b0541a8.js +1 -0
- package/packages/web/130.584c7e365da413f5d9be.js +1 -0
- package/packages/web/142.72c985bc29720f975cca.js +1 -0
- package/packages/web/165.a05fc53bf84d18db36b8.js +2 -0
- package/packages/web/165.a05fc53bf84d18db36b8.js.LICENSE.txt +9 -0
- package/packages/web/203.724ab9f717b80554c397.js +1 -0
- package/packages/web/241.bf941d4f02866795f64a.js +1 -0
- package/packages/web/249.54cfb224af63f5f5ec55.js +1 -0
- package/packages/web/291.6df35042f8f296fca7cd.js +1 -0
- package/packages/web/319.2fab900a31b29873f666.js +1 -0
- package/packages/web/32.c78d866281995ec33a7b.js +1 -0
- package/packages/web/325.9ca297d0f73f38468ce9.js +1 -0
- package/packages/web/366.2f9b48fdbf8eee039e57.js +1 -0
- package/packages/web/378.6be08c612cd5a3ef97dc.js +1 -0
- package/packages/web/393.7a2f817515c5e90623d7.js +1 -0
- package/packages/web/412.062df5f732d5ba203415.js +1 -0
- package/packages/web/426.08656fef4918b3fb19ad.js +1 -0
- package/packages/web/465.2be8018327130a3bd798.js +1 -0
- package/packages/web/48.8ca96fc93667a715e67a.js +1 -0
- package/packages/web/480.44c1f1a2927486ac3d4f.js +1 -0
- package/packages/web/489.e041a8d0db15dc96d607.js +1 -0
- package/packages/web/490.9ffb26c907de020d671b.js +1 -0
- package/packages/web/492.58781369e348d91fc06a.js +1 -0
- package/packages/web/495.ed63e99791a87167c6b3.js +1 -0
- package/packages/web/510.4cc07ab7d30d5c1cd17f.js +1 -0
- package/packages/web/543.3af155ed4fa237664308.js +1 -0
- package/packages/web/567.f04ab60f8e2c2fb0745a.js +1 -0
- package/packages/web/592.f3ad085fa9c1849daa06.js +1 -0
- package/packages/web/616.b03fb801b3433b17750f.js +1 -0
- package/packages/web/617.d88def54921d2c4dc44c.js +1 -0
- package/packages/web/641.d30787d674f548928261.js +1 -0
- package/packages/web/672.5269c8399fa42a5af95d.js +1 -0
- package/packages/web/731.97cab92b71811c502bda.js +1 -0
- package/packages/web/746.3947c6f0235407e420fb.js +1 -0
- package/packages/web/756.a53233b3f3913900d5ac.js +1 -0
- package/packages/web/77.68801af593a28a631fbf.js +1 -0
- package/packages/web/802.53b2bff3cf2a69f7b80c.js +1 -0
- package/packages/web/815.b6dfab82265f56c7e046.js +1 -0
- package/packages/web/821.f5a13e5c735aac244eb9.js +1 -0
- package/packages/web/846.b9bf97d5f559270675ce.js +1 -0
- package/packages/web/869.7c10403f500e6201407f.js +1 -0
- package/packages/web/885.135050364f99e6924fb5.js +1 -0
- package/packages/web/901.fd5aeb9df630609a2b43.js +1 -0
- package/packages/web/928.f67e590de3caa4daa3ae.js +1 -0
- package/packages/web/955.d833403521ba4dd567ee.js +1 -0
- package/packages/web/981.a45cb745cf424044c8c8.js +1 -0
- package/packages/web/992.645320b60c74c8787482.js +1 -0
- package/packages/web/996.ed9a963dc9e7439eca9a.js +1 -0
- package/packages/{admin-ui/css/main.css → web/css/main.3b61356b384d2f11f47f.css} +2793 -10
- package/packages/web/index.html +3 -0
- package/packages/web/main.77c2c4b553ca3fac223b.js +2 -0
- package/packages/web/main.77c2c4b553ca3fac223b.js.LICENSE.txt +3 -0
- package/packages/admin-ui/admin.html +0 -49
- package/packages/admin-ui/css/markdown.css +0 -468
- package/packages/admin-ui/css/optimization.css +0 -1015
- package/packages/admin-ui/css/recommended-prompts.css +0 -610
- package/packages/admin-ui/css/terminal-fix.css +0 -571
- package/packages/admin-ui/package-lock.json +0 -8287
- package/packages/admin-ui/package.json +0 -46
- package/packages/admin-ui/src/codemirror.js +0 -53
- package/packages/admin-ui/src/components/ArgumentModal.js +0 -53
- package/packages/admin-ui/src/components/DeletePromptModal.js +0 -30
- package/packages/admin-ui/src/components/HeaderView.js +0 -40
- package/packages/admin-ui/src/components/LoadingOverlay.js +0 -12
- package/packages/admin-ui/src/components/LoginView.js +0 -22
- package/packages/admin-ui/src/components/ModelConfigModal.js +0 -103
- package/packages/admin-ui/src/components/NewFolderModal.js +0 -58
- package/packages/admin-ui/src/components/OptimizationConfigModal.js +0 -36
- package/packages/admin-ui/src/components/OptimizationDrawer.js +0 -135
- package/packages/admin-ui/src/components/PrimaryNav.js +0 -34
- package/packages/admin-ui/src/components/PromptsArea.js +0 -140
- package/packages/admin-ui/src/components/RecommendedPromptModal.js +0 -37
- package/packages/admin-ui/src/components/SidebarView.js +0 -24
- package/packages/admin-ui/src/components/SyncPromptModal.js +0 -44
- package/packages/admin-ui/src/components/TemplateEditorModal.js +0 -75
- package/packages/admin-ui/src/components/TemplateListModal.js +0 -30
- package/packages/admin-ui/src/components/TerminalComponent.js +0 -995
- package/packages/admin-ui/src/components/TerminalView.js +0 -25
- package/packages/admin-ui/src/components/ToolDetailModal.js +0 -23
- package/packages/admin-ui/src/components/ToolsArea.js +0 -119
- package/packages/admin-ui/src/components/ToolsUploadModal.js +0 -59
- package/packages/admin-ui/src/index.js +0 -6766
- /package/packages/{admin-ui → web}/css/codemirror-theme_xq-light.css +0 -0
- /package/packages/{admin-ui → web}/css/codemirror.css +0 -0
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@becrafter/admin-ui",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"description": "Admin UI for Prompt Manager",
|
|
5
|
-
"scripts": {
|
|
6
|
-
"dev": "npx webpack serve --mode development",
|
|
7
|
-
"build": "npx webpack --mode production",
|
|
8
|
-
"serve": "npx http-server . -p 8080 -o"
|
|
9
|
-
},
|
|
10
|
-
"keywords": [
|
|
11
|
-
"admin",
|
|
12
|
-
"ui",
|
|
13
|
-
"prompt-manager"
|
|
14
|
-
],
|
|
15
|
-
"author": "BeCrafter",
|
|
16
|
-
"license": "MIT",
|
|
17
|
-
"devDependencies": {
|
|
18
|
-
"@babel/core": "^7.28.5",
|
|
19
|
-
"@babel/preset-env": "^7.28.5",
|
|
20
|
-
"babel-loader": "^10.0.0",
|
|
21
|
-
"copy-webpack-plugin": "^11.0.0",
|
|
22
|
-
"css-loader": "^6.8.0",
|
|
23
|
-
"file-loader": "^6.2.0",
|
|
24
|
-
"html-webpack-plugin": "^5.5.0",
|
|
25
|
-
"mini-css-extract-plugin": "^2.9.4",
|
|
26
|
-
"source-map-loader": "^5.0.0",
|
|
27
|
-
"style-loader": "^3.3.0",
|
|
28
|
-
"terser-webpack-plugin": "^5.3.0",
|
|
29
|
-
"webpack": "^5.88.0",
|
|
30
|
-
"webpack-cli": "^5.1.4",
|
|
31
|
-
"webpack-dev-server": "^4.15.0"
|
|
32
|
-
},
|
|
33
|
-
"dependencies": {
|
|
34
|
-
"codemirror": "5.65.2",
|
|
35
|
-
"highlight.js": "^11.11.1",
|
|
36
|
-
"js-yaml": "^4.1.0",
|
|
37
|
-
"marked": "^17.0.1",
|
|
38
|
-
"mermaid": "^11.12.2",
|
|
39
|
-
"xterm": "^5.3.0",
|
|
40
|
-
"xterm-addon-fit": "^0.8.0",
|
|
41
|
-
"xterm-addon-web-links": "^0.9.0",
|
|
42
|
-
"xterm-addon-search": "^0.13.0",
|
|
43
|
-
"xterm-addon-unicode11": "^0.6.0",
|
|
44
|
-
"xterm-addon-canvas": "^0.5.0"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// src/codemirror.js - CodeMirror 初始化和配置
|
|
2
|
-
|
|
3
|
-
import CodeMirror from "codemirror"
|
|
4
|
-
import "codemirror/mode/markdown/markdown"
|
|
5
|
-
import "codemirror/addon/edit/closebrackets"
|
|
6
|
-
import "codemirror/addon/edit/matchbrackets"
|
|
7
|
-
import yaml from "js-yaml"
|
|
8
|
-
|
|
9
|
-
// 将 js-yaml 挂载到 window 对象上,以便其他地方可以访问
|
|
10
|
-
window.jsyaml = yaml
|
|
11
|
-
|
|
12
|
-
// 初始化 CodeMirror 编辑器
|
|
13
|
-
function initCodeMirror() {
|
|
14
|
-
const editorElement = document.getElementById('editor')
|
|
15
|
-
const initialValue = editorElement.value || '' // 改为空字符串,使编辑器初始化时为空白
|
|
16
|
-
|
|
17
|
-
const editor = CodeMirror.fromTextArea(editorElement, {
|
|
18
|
-
mode: 'markdown',
|
|
19
|
-
theme: 'xq-light',
|
|
20
|
-
lineNumbers: false,
|
|
21
|
-
lineWrapping: true,
|
|
22
|
-
autoCloseBrackets: true,
|
|
23
|
-
matchBrackets: true,
|
|
24
|
-
indentUnit: 2,
|
|
25
|
-
tabSize: 2,
|
|
26
|
-
fontSize: '14px',
|
|
27
|
-
height: '100%',
|
|
28
|
-
viewportMargin: Infinity
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
// 设置初始值
|
|
32
|
-
editor.setValue(initialValue)
|
|
33
|
-
|
|
34
|
-
// 监听内容变化以更新预览
|
|
35
|
-
editor.on('change', function() {
|
|
36
|
-
// 延迟更新预览以避免过于频繁的更新
|
|
37
|
-
clearTimeout(window.previewUpdateTimer)
|
|
38
|
-
window.previewUpdateTimer = setTimeout(() => {
|
|
39
|
-
if (typeof updatePreview === 'function') {
|
|
40
|
-
updatePreview()
|
|
41
|
-
}
|
|
42
|
-
}, 300)
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
// 将 editor 对象暴露出去,以便可以获取内容
|
|
46
|
-
// 不需要重写 getValue 和 setValue 方法,因为 CodeMirror 已经提供了它们
|
|
47
|
-
// editor.getValue = () => editor.getValue()
|
|
48
|
-
// editor.setValue = (value) => editor.setValue(value)
|
|
49
|
-
|
|
50
|
-
return editor
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export { initCodeMirror }
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
export class ArgumentModal {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="argumentModal" class="argument-modal hidden" role="dialog" aria-modal="true" aria-labelledby="argumentModalTitle">
|
|
5
|
-
<div class="argument-modal-dialog">
|
|
6
|
-
<div class="argument-modal-header">
|
|
7
|
-
<h3 id="argumentModalTitle">新增参数</h3>
|
|
8
|
-
<button type="button" id="argumentModalClose" class="argument-modal-close" aria-label="关闭">×</button>
|
|
9
|
-
</div>
|
|
10
|
-
<form id="argumentForm" class="argument-modal-form">
|
|
11
|
-
<div class="argument-modal-body">
|
|
12
|
-
<div class="argument-form-grid">
|
|
13
|
-
<div class="form-field required-field">
|
|
14
|
-
<label for="argumentNameInput">参数名称 <span class="required">*</span></label>
|
|
15
|
-
<input type="text" id="argumentNameInput" name="argumentName" placeholder="例如:language" />
|
|
16
|
-
</div>
|
|
17
|
-
<div class="form-field">
|
|
18
|
-
<label for="argumentTypeInput">类型</label>
|
|
19
|
-
<input type="text" id="argumentTypeInput" name="argumentType" list="argumentTypeOptions" placeholder="例如:string" />
|
|
20
|
-
</div>
|
|
21
|
-
<div class="form-field">
|
|
22
|
-
<label for="argumentDefaultInput">默认值</label>
|
|
23
|
-
<input type="text" id="argumentDefaultInput" name="argumentDefault" placeholder="可选" />
|
|
24
|
-
</div>
|
|
25
|
-
<div class="form-field form-field-inline">
|
|
26
|
-
<label class="checkbox-field">
|
|
27
|
-
<input type="checkbox" id="argumentRequiredInput" />
|
|
28
|
-
<span>必填</span>
|
|
29
|
-
</label>
|
|
30
|
-
</div>
|
|
31
|
-
<div class="form-field full-width">
|
|
32
|
-
<label for="argumentDescriptionInput">参数说明</label>
|
|
33
|
-
<textarea id="argumentDescriptionInput" rows="3" placeholder="用于提示词中的描述"></textarea>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
<div class="argument-modal-footer">
|
|
38
|
-
<button type="button" class="btn btn-outline" id="argumentCancelBtn">取消</button>
|
|
39
|
-
<button type="submit" class="btn btn-primary">保存</button>
|
|
40
|
-
</div>
|
|
41
|
-
</form>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
|
|
45
|
-
<datalist id="argumentTypeOptions">
|
|
46
|
-
<option value="string">字符串</option>
|
|
47
|
-
<option value="number">数字</option>
|
|
48
|
-
<option value="boolean">布尔值</option>
|
|
49
|
-
</datalist>
|
|
50
|
-
`;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export class DeletePromptModal {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="deletePromptModal" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="deletePromptTitle">
|
|
5
|
-
<div class="modal-dialog">
|
|
6
|
-
<div class="modal-content">
|
|
7
|
-
<div class="modal-header">
|
|
8
|
-
<h3 id="deletePromptTitle">删除 Prompt</h3>
|
|
9
|
-
<button type="button" class="modal-close" id="deletePromptCloseBtn" aria-label="关闭">
|
|
10
|
-
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
11
|
-
<path d="M15 5L5 15M5 5L15 15" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
|
-
</svg>
|
|
13
|
-
</button>
|
|
14
|
-
</div>
|
|
15
|
-
<div class="modal-body">
|
|
16
|
-
<p style="font-size: 14px; color: var(--gray); line-height: 1.6;">
|
|
17
|
-
确认删除 <span id="deletePromptName" style="color: var(--dark); font-weight: 600;"></span> 吗?该操作不可撤销。
|
|
18
|
-
</p>
|
|
19
|
-
</div>
|
|
20
|
-
<div class="modal-footer">
|
|
21
|
-
<button type="button" class="btn btn-light" id="deletePromptCancelBtn">取消</button>
|
|
22
|
-
<button type="button" class="btn btn-danger" id="deletePromptConfirmBtn">删除</button>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
`;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export class HeaderView {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<header>
|
|
5
|
-
<div class="logo">
|
|
6
|
-
Prompt Manager <span>Beta</span>
|
|
7
|
-
</div>
|
|
8
|
-
<div class="nav-right">
|
|
9
|
-
<a href="https://github.com/BeCrafter/prompt-manager" target="_blank" class="github-link" title="查看 GitHub 项目">
|
|
10
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
|
11
|
-
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
12
|
-
</svg>
|
|
13
|
-
</a>
|
|
14
|
-
<div class="user-profile hidden">
|
|
15
|
-
<button class="avatar-btn" id="avatarBtn" aria-haspopup="true" aria-expanded="false">
|
|
16
|
-
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%239ca3af'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z'/%3E%3C/svg%3E" alt="用户头像" class="avatar-img">
|
|
17
|
-
</button>
|
|
18
|
-
<div class="dropdown-menu" id="userMenu">
|
|
19
|
-
<div class="dropdown-header">
|
|
20
|
-
<div class="user-info">
|
|
21
|
-
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%239ca3af'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 3c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 14.2c-2.5 0-4.71-1.28-6-3.22.03-1.99 4-3.08 6-3.08 1.99 0 5.97 1.09 6 3.08-1.29 1.94-3.5 3.22-6 3.22z'/%3E%3C/svg%3E" alt="用户头像" class="user-avatar">
|
|
22
|
-
<div class="user-details">
|
|
23
|
-
<div class="user-name">管理员</div>
|
|
24
|
-
<div class="user-role">Admin</div>
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
<div class="dropdown-divider"></div>
|
|
29
|
-
<button id="logoutBtn" class="dropdown-item">
|
|
30
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="dropdown-icon"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line></svg>
|
|
31
|
-
退出登录
|
|
32
|
-
</button>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
</header>
|
|
37
|
-
`;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export class LoadingOverlay {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="loadingOverlay" class="loading-overlay hidden">
|
|
5
|
-
<div class="loading-spinner"></div>
|
|
6
|
-
<div class="loading-text">正在加载中...</div>
|
|
7
|
-
<div class="loading-subtext">请稍候,正在获取数据</div>
|
|
8
|
-
</div>
|
|
9
|
-
`;
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export class LoginView {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="login" class="login-container" style="display: none;">
|
|
5
|
-
<form id="loginForm" class="login-form">
|
|
6
|
-
<div class="login-box">
|
|
7
|
-
<h2>Prompt Manager</h2>
|
|
8
|
-
<div class="input-group username">
|
|
9
|
-
<input type="text" id="username" name="username" placeholder="用户名" autocomplete="username" />
|
|
10
|
-
</div>
|
|
11
|
-
<div class="input-group password">
|
|
12
|
-
<input type="password" id="password" name="password" placeholder="密码" autocomplete="current-password" />
|
|
13
|
-
</div>
|
|
14
|
-
<button type="submit" id="loginBtn" class="btn btn-primary">登 录</button>
|
|
15
|
-
<div id="loginError" class="error-msg" style="display: none; margin-top: 15px;"></div>
|
|
16
|
-
</div>
|
|
17
|
-
</form>
|
|
18
|
-
</div>
|
|
19
|
-
`;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
export class ModelConfigModal {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="modelConfigModal" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="modelConfigModalTitle">
|
|
5
|
-
<div class="modal-dialog">
|
|
6
|
-
<div class="modal-content">
|
|
7
|
-
<div class="modal-header">
|
|
8
|
-
<h3 id="modelConfigModalTitle">模型配置</h3>
|
|
9
|
-
<button type="button" id="modelConfigModalClose" class="modal-close" aria-label="关闭">×</button>
|
|
10
|
-
</div>
|
|
11
|
-
<div class="modal-body">
|
|
12
|
-
<div class="model-list-header">
|
|
13
|
-
<button type="button" id="createModelBtn" class="btn btn-primary">
|
|
14
|
-
+ 新增模型
|
|
15
|
-
</button>
|
|
16
|
-
</div>
|
|
17
|
-
<div id="modelList" class="model-list">
|
|
18
|
-
<!-- 动态加载模型列表 -->
|
|
19
|
-
</div>
|
|
20
|
-
</div>
|
|
21
|
-
<div class="modal-footer">
|
|
22
|
-
<button type="button" id="modelConfigCloseBtn" class="btn btn-light">关闭</button>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
</div>
|
|
27
|
-
|
|
28
|
-
<!-- 模型编辑模态框(嵌套) -->
|
|
29
|
-
<div id="modelEditorModal" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="modelEditorModalTitle">
|
|
30
|
-
<div class="modal-dialog">
|
|
31
|
-
<div class="modal-content">
|
|
32
|
-
<div class="modal-header">
|
|
33
|
-
<h3 id="modelEditorModalTitle">编辑模型</h3>
|
|
34
|
-
<button type="button" id="modelEditorModalClose" class="modal-close" aria-label="关闭">×</button>
|
|
35
|
-
</div>
|
|
36
|
-
<div class="modal-body">
|
|
37
|
-
<div class="form-info-box">
|
|
38
|
-
<h4>ℹ️ OpenAPI 规范要求</h4>
|
|
39
|
-
<p>模型配置需符合 OpenAI 兼容的 API 规范,确保请求和响应格式正确:</p>
|
|
40
|
-
<ul>
|
|
41
|
-
<li><strong>API 端点</strong>:需指向 <code>/chat/completions</code> 接口</li>
|
|
42
|
-
<li><strong>请求格式</strong>:JSON 格式,包含 <code>model</code> 和 <code>messages</code> 字段</li>
|
|
43
|
-
<li><strong>响应格式</strong>:支持流式输出(SSE)或标准 JSON 响应</li>
|
|
44
|
-
<li><strong>认证方式</strong>:使用 Bearer Token(API Key)</li>
|
|
45
|
-
</ul>
|
|
46
|
-
<p class="form-info-example">
|
|
47
|
-
示例端点:<code>https://api.openai.com/v1/chat/completions</code>
|
|
48
|
-
</p>
|
|
49
|
-
</div>
|
|
50
|
-
<form id="modelForm">
|
|
51
|
-
<div class="form-group">
|
|
52
|
-
<label for="modelName">名称 <span class="required">*</span></label>
|
|
53
|
-
<input type="text" id="modelName" class="form-control" required placeholder="例如:OpenAI GPT-4" />
|
|
54
|
-
</div>
|
|
55
|
-
<div class="form-group">
|
|
56
|
-
<label for="modelProvider">提供商 <span class="required">*</span></label>
|
|
57
|
-
<select id="modelProvider" class="form-control" required>
|
|
58
|
-
<option value="">请选择提供商</option>
|
|
59
|
-
<!-- 动态加载提供商选项 -->
|
|
60
|
-
</select>
|
|
61
|
-
<small class="form-text">选择提供商可自动填充默认配置</small>
|
|
62
|
-
</div>
|
|
63
|
-
<div class="form-group">
|
|
64
|
-
<label for="modelModel">模型 <span class="required">*</span></label>
|
|
65
|
-
<select id="modelModelSelect" class="form-control" required style="margin-bottom: 8px;">
|
|
66
|
-
<option value="">请选择模型</option>
|
|
67
|
-
<!-- 动态加载模型选项 -->
|
|
68
|
-
</select>
|
|
69
|
-
<div id="customModelInput" class="custom-model-input" style="display: none;">
|
|
70
|
-
<input type="text" id="modelModelCustom" class="form-control" placeholder="或输入自定义模型名称" />
|
|
71
|
-
</div>
|
|
72
|
-
<div id="modelModelHint" style="display: none;">
|
|
73
|
-
<a href="#" id="useCustomModel" style="font-size: 12px; color: #1890ff;">使用自定义模型</a>
|
|
74
|
-
</div>
|
|
75
|
-
</div>
|
|
76
|
-
<div class="form-group">
|
|
77
|
-
<label for="modelApiEndpoint">API 端点 <span class="required">*</span></label>
|
|
78
|
-
<input type="url" id="modelApiEndpoint" class="form-control" required placeholder="https://api.openai.com/v1/chat/completions" />
|
|
79
|
-
<small class="form-text">必须指向 /chat/completions 接口</small>
|
|
80
|
-
</div>
|
|
81
|
-
<div class="form-group">
|
|
82
|
-
<label for="modelApiKey">API Key</label>
|
|
83
|
-
<input type="password" id="modelApiKey" class="form-control" placeholder="请输入 API Key" />
|
|
84
|
-
<small class="form-text">用于 Bearer Token 认证</small>
|
|
85
|
-
</div>
|
|
86
|
-
<div class="form-group">
|
|
87
|
-
<label class="checkbox-field">
|
|
88
|
-
<input type="checkbox" id="modelEnabled" checked />
|
|
89
|
-
<span>启用此模型</span>
|
|
90
|
-
</label>
|
|
91
|
-
</div>
|
|
92
|
-
</form>
|
|
93
|
-
</div>
|
|
94
|
-
<div class="modal-footer">
|
|
95
|
-
<button type="button" id="cancelModelBtn" class="btn btn-light">取消</button>
|
|
96
|
-
<button type="button" id="saveModelBtn" class="btn btn-primary">保存</button>
|
|
97
|
-
</div>
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
</div>
|
|
101
|
-
`;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
export class NewFolderModal {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="newFolderModal" class="modal hidden">
|
|
5
|
-
<div class="modal-dialog">
|
|
6
|
-
<div class="modal-content group-modal-content">
|
|
7
|
-
<div class="modal-header">
|
|
8
|
-
<h3>类目管理</h3>
|
|
9
|
-
<button type="button" class="modal-close" onclick="window.toggleNewFolderModal()">
|
|
10
|
-
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
|
11
|
-
<path d="M15 5L5 15M5 5L15 15" stroke="currentColor" stroke-width="1.67" stroke-linecap="round" stroke-linejoin="round"/>
|
|
12
|
-
</svg>
|
|
13
|
-
</button>
|
|
14
|
-
</div>
|
|
15
|
-
<div class="modal-body">
|
|
16
|
-
<div class="group-modal-tabs">
|
|
17
|
-
<button type="button" class="group-modal-tab active" data-tab="create">新增类目</button>
|
|
18
|
-
<button type="button" class="group-modal-tab" data-tab="manage">管理类目</button>
|
|
19
|
-
</div>
|
|
20
|
-
<div class="group-modal-panel" data-panel="create">
|
|
21
|
-
<div class="form-group">
|
|
22
|
-
<label>目录名称</label>
|
|
23
|
-
<input type="text" id="newFolderName" name="folderName" placeholder="请输入目录名称" onkeydown="window.handleNewFolderKeydown(event)">
|
|
24
|
-
<div class="group-modal-hint">名称仅支持字母、数字、下划线、短横线和中文,长度不超过64个字符。</div>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="form-group">
|
|
27
|
-
<label>父级目录</label>
|
|
28
|
-
<select id="newFolderParent" class="form-control">
|
|
29
|
-
<option value="">根目录</option>
|
|
30
|
-
</select>
|
|
31
|
-
<div class="group-modal-hint">选择父级目录以创建子目录</div>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
<div class="group-modal-panel hidden" data-panel="manage">
|
|
35
|
-
<div class="group-manage-toolbar">
|
|
36
|
-
<input type="text" id="groupManageSearch" placeholder="搜索类目..." />
|
|
37
|
-
<button type="button" class="btn btn-light btn-sm" id="groupManageRefreshBtn">刷新</button>
|
|
38
|
-
</div>
|
|
39
|
-
<div class="group-manage-list" id="groupManageList"></div>
|
|
40
|
-
<div class="group-manage-empty hidden" id="groupManageEmpty">暂无类目信息</div>
|
|
41
|
-
</div>
|
|
42
|
-
</div>
|
|
43
|
-
<div class="modal-footer">
|
|
44
|
-
<div class="group-modal-footer group-modal-footer-create" id="groupModalCreateFooter">
|
|
45
|
-
<button type="button" class="btn btn-light" onclick="window.toggleNewFolderModal()">取消</button>
|
|
46
|
-
<button type="button" class="btn btn-dark" onclick="window.createNewFolder()">创建</button>
|
|
47
|
-
</div>
|
|
48
|
-
<div class="group-modal-footer group-modal-footer-manage hidden" id="groupModalManageFooter">
|
|
49
|
-
<button type="button" class="btn btn-light" onclick="window.toggleNewFolderModal(false)">关闭</button>
|
|
50
|
-
</div>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
`;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
export class OptimizationConfigModal {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="optimizationConfigModal" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="optimizationConfigModalTitle">
|
|
5
|
-
<div class="modal-dialog">
|
|
6
|
-
<div class="modal-content">
|
|
7
|
-
<div class="modal-header">
|
|
8
|
-
<h3 id="optimizationConfigModalTitle">优化配置</h3>
|
|
9
|
-
<button type="button" id="optimizationConfigModalClose" class="modal-close" aria-label="关闭">×</button>
|
|
10
|
-
</div>
|
|
11
|
-
<div class="modal-body">
|
|
12
|
-
<form id="optimizationConfigForm">
|
|
13
|
-
<div class="form-group">
|
|
14
|
-
<label for="maxIterations">最大迭代次数</label>
|
|
15
|
-
<input type="number" id="maxIterations" class="form-control" min="1" max="20" value="10" />
|
|
16
|
-
<small class="form-text">单次会话中允许的最大迭代优化次数</small>
|
|
17
|
-
</div>
|
|
18
|
-
<div class="form-group">
|
|
19
|
-
<label class="checkbox-field">
|
|
20
|
-
<input type="checkbox" id="encryptionEnabled" checked disabled />
|
|
21
|
-
<span>启用 API Key 加密</span>
|
|
22
|
-
</label>
|
|
23
|
-
<small class="form-text">API Key 将使用 AES-256 加密存储</small>
|
|
24
|
-
</div>
|
|
25
|
-
</form>
|
|
26
|
-
</div>
|
|
27
|
-
<div class="modal-footer">
|
|
28
|
-
<button type="button" id="optimizationConfigCloseBtn" class="btn btn-light">关闭</button>
|
|
29
|
-
<button type="button" id="saveOptimizationConfigBtn" class="btn btn-primary">保存</button>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
</div>
|
|
33
|
-
</div>
|
|
34
|
-
`;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
export class OptimizationDrawer {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<div id="optimizationDrawer" class="optimization-drawer hidden">
|
|
5
|
-
<div class="drawer-overlay"></div>
|
|
6
|
-
<div class="drawer-content">
|
|
7
|
-
<div class="drawer-header">
|
|
8
|
-
<h3>AI 优化</h3>
|
|
9
|
-
<button type="button" id="closeDrawerBtn" class="drawer-close" aria-label="关闭">×</button>
|
|
10
|
-
</div>
|
|
11
|
-
<div class="drawer-body">
|
|
12
|
-
<!-- 原始提示词 -->
|
|
13
|
-
<div class="original-prompt-section">
|
|
14
|
-
<h4>原始提示词</h4>
|
|
15
|
-
<textarea id="originalEditor" class="form-control" rows="8" placeholder="输入要优化的提示词..."></textarea>
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
<!-- 优化控制区域 -->
|
|
19
|
-
<div class="optimization-controls">
|
|
20
|
-
<div class="optimization-controls-row">
|
|
21
|
-
<!-- 模型选择 -->
|
|
22
|
-
<div class="control-group model-selector">
|
|
23
|
-
<div class="custom-select" id="modelSelectWrapper">
|
|
24
|
-
<div class="custom-select-trigger placeholder" id="modelSelectTrigger">
|
|
25
|
-
<span>优化模型</span>
|
|
26
|
-
<svg class="custom-select-arrow" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
27
|
-
<path d="M2.5 4.5L6 8L9.5 4.5" stroke="#999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
28
|
-
</svg>
|
|
29
|
-
</div>
|
|
30
|
-
<div class="custom-select-options" id="modelSelectOptions">
|
|
31
|
-
<div class="custom-select-option" data-value="">请选择模型</div>
|
|
32
|
-
<div class="custom-select-divider"></div>
|
|
33
|
-
<div class="custom-select-action" id="configModelAction">
|
|
34
|
-
<span>⚙️ 配置模型</span>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
|
|
40
|
-
<!-- 模板选择 -->
|
|
41
|
-
<div class="control-group template-selector">
|
|
42
|
-
<div class="custom-select" id="templateSelectWrapper">
|
|
43
|
-
<div class="custom-select-trigger placeholder" id="templateSelectTrigger">
|
|
44
|
-
<span>优化提示词</span>
|
|
45
|
-
<svg class="custom-select-arrow" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
46
|
-
<path d="M2.5 4.5L6 8L9.5 4.5" stroke="#999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
47
|
-
</svg>
|
|
48
|
-
</div>
|
|
49
|
-
<div class="custom-select-options" id="templateSelectOptions">
|
|
50
|
-
<div class="custom-select-option" data-value="">请选择模板</div>
|
|
51
|
-
<div class="custom-select-divider"></div>
|
|
52
|
-
<div class="custom-select-action" id="configTemplateAction">
|
|
53
|
-
<span>⚙️ 配置模板</span>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
|
|
59
|
-
<!-- 开始优化按钮 -->
|
|
60
|
-
<button type="button" id="startOptimizeBtn" class="btn btn-primary" disabled>
|
|
61
|
-
开始优化 →
|
|
62
|
-
</button>
|
|
63
|
-
</div>
|
|
64
|
-
</div>
|
|
65
|
-
|
|
66
|
-
<!-- 优化结果(流式输出) -->
|
|
67
|
-
<div class="optimized-result-section">
|
|
68
|
-
<div class="result-header">
|
|
69
|
-
<h4>优化后的提示词</h4>
|
|
70
|
-
<button type="button" id="iterateBtn" class="btn btn-outline btn-sm" disabled>
|
|
71
|
-
继续优化
|
|
72
|
-
</button>
|
|
73
|
-
</div>
|
|
74
|
-
<div id="optimizedOutput" class="optimized-output">
|
|
75
|
-
<p class="placeholder-text">优化结果将在这里显示...</p>
|
|
76
|
-
</div>
|
|
77
|
-
</div>
|
|
78
|
-
</div>
|
|
79
|
-
<div class="drawer-footer">
|
|
80
|
-
<button type="button" id="cancelBtn" class="btn btn-outline">取消</button>
|
|
81
|
-
<button type="button" id="applyOptimizationBtn" class="btn btn-primary" disabled>应用优化</button>
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
</div>
|
|
85
|
-
|
|
86
|
-
<!-- 迭代优化指导弹窗 -->
|
|
87
|
-
<div id="iterationGuideModal" class="modal hidden" role="dialog" aria-modal="true" aria-labelledby="iterationGuideModalTitle">
|
|
88
|
-
<div class="modal-dialog">
|
|
89
|
-
<div class="modal-content">
|
|
90
|
-
<div class="modal-header">
|
|
91
|
-
<h3 id="iterationGuideModalTitle">继续优化 - 输入优化指导</h3>
|
|
92
|
-
<button type="button" id="iterationGuideModalClose" class="modal-close" aria-label="关闭">×</button>
|
|
93
|
-
</div>
|
|
94
|
-
<div class="modal-body">
|
|
95
|
-
<div class="form-info-box">
|
|
96
|
-
<h4>💡 优化指导说明</h4>
|
|
97
|
-
<p>请输入您希望本次迭代优化的具体方向或要求,例如:</p>
|
|
98
|
-
<ul>
|
|
99
|
-
<li>让提示词更加简洁明了</li>
|
|
100
|
-
<li>增加对输出格式的详细要求</li>
|
|
101
|
-
<li>优化角色定义的专业性</li>
|
|
102
|
-
<li>增强提示词的容错能力</li>
|
|
103
|
-
<li>调整语气和风格</li>
|
|
104
|
-
</ul>
|
|
105
|
-
</div>
|
|
106
|
-
<div class="form-group">
|
|
107
|
-
<label for="iterationTemplate">迭代模板 <span class="required">*</span></label>
|
|
108
|
-
<div class="custom-select" id="iterationTemplateSelectWrapper">
|
|
109
|
-
<div class="custom-select-trigger placeholder" id="iterationTemplateSelectTrigger">
|
|
110
|
-
<span>选择迭代模板</span>
|
|
111
|
-
<svg class="custom-select-arrow" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
112
|
-
<path d="M2.5 4.5L6 8L9.5 4.5" stroke="#999" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
113
|
-
</svg>
|
|
114
|
-
</div>
|
|
115
|
-
<div class="custom-select-options" id="iterationTemplateSelectOptions">
|
|
116
|
-
<!-- 迭代模板选项 -->
|
|
117
|
-
</div>
|
|
118
|
-
</div>
|
|
119
|
-
</div>
|
|
120
|
-
<div class="form-group">
|
|
121
|
-
<label for="iterationGuide">优化指导 <span class="optional">(可选)</span></label>
|
|
122
|
-
<textarea id="iterationGuide" class="form-control" rows="4" placeholder="请输入您希望优化的具体方向或要求..."></textarea>
|
|
123
|
-
<small class="form-text">如果不输入,将基于上一次的优化结果自动继续优化</small>
|
|
124
|
-
</div>
|
|
125
|
-
</div>
|
|
126
|
-
<div class="modal-footer">
|
|
127
|
-
<button type="button" id="cancelIterationBtn" class="btn btn-outline">取消</button>
|
|
128
|
-
<button type="button" id="confirmIterationBtn" class="btn btn-primary" disabled>开始迭代优化</button>
|
|
129
|
-
</div>
|
|
130
|
-
</div>
|
|
131
|
-
</div>
|
|
132
|
-
</div>
|
|
133
|
-
`;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
export class PrimaryNav {
|
|
2
|
-
static getHTML() {
|
|
3
|
-
return `
|
|
4
|
-
<nav class="primary-nav">
|
|
5
|
-
<div class="primary-nav-items">
|
|
6
|
-
<button class="primary-nav-item active" data-nav="prompts" title="Prompts">
|
|
7
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
8
|
-
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
|
|
9
|
-
<polyline points="14 2 14 8 20 8"></polyline>
|
|
10
|
-
<line x1="16" y1="13" x2="8" y2="13"></line>
|
|
11
|
-
<line x1="16" y1="17" x2="8" y2="17"></line>
|
|
12
|
-
<polyline points="10 9 9 9 8 9"></polyline>
|
|
13
|
-
</svg>
|
|
14
|
-
<span>Prompts</span>
|
|
15
|
-
</button>
|
|
16
|
-
<button class="primary-nav-item" data-nav="tools" title="Tools">
|
|
17
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
18
|
-
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path>
|
|
19
|
-
</svg>
|
|
20
|
-
<span>Tools</span>
|
|
21
|
-
</button>
|
|
22
|
-
<button class="primary-nav-item" data-nav="terminal" title="Terminal">
|
|
23
|
-
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
24
|
-
<polyline points="4 17 10 11 4 5"></polyline>
|
|
25
|
-
<line x1="12" x2="20" y1="19" y2="19"></line>
|
|
26
|
-
</svg>
|
|
27
|
-
<span>Terminal</span>
|
|
28
|
-
</button>
|
|
29
|
-
</div>
|
|
30
|
-
</nav>
|
|
31
|
-
`;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|