try vscode plugin

This commit is contained in:
CakeCN
2025-09-11 01:06:14 +08:00
parent 2da2da1208
commit 3109cc94e2
16 changed files with 481 additions and 35 deletions

View File

@@ -14,7 +14,8 @@ if __name__ == "__main__":
host="0.0.0.0",
port=5551,
debug=True, # 开发期打开
allow_unsafe_werkzeug=True # 避免 dev server 的安全限制提示
allow_unsafe_werkzeug=True, # 避免 dev server 的安全限制提示
ssl_context=('server.crt', 'server.key')
)

View File

@@ -1 +1,2 @@
from .client import ASEngineClient
from .client import ASEngineClient, HSAEngineClient
from .manager import ChatManager

View File

@@ -56,9 +56,6 @@ class ASEngineClient:
def on_response(data):
print(f"Received response: {data}")
def register_route_with_entry(self, route: str,
callback: Optional[Callable] = None,
entry: Any = None,
@@ -167,9 +164,6 @@ class ASEngineClient:
print("Not connected to server")
return False
if route not in self.routes:
print(f"Route '{route}' not registered")
return False
try:
self.sio.emit(route, {'type': 'text', 'data': text}, namespace=self.namespace)
@@ -265,3 +259,13 @@ class ASEngineClient:
self.disconnect()
else:
print("Not connected to server")
class HSAEngineClient(ASEngineClient):
def __init__(self, server_url: str, namespace: str):
super().__init__(server_url, namespace)
def loadmarkdown(self, fmd, fmdp, fsp):
self.send_text('markdown-in', fmd)
self.send_text('markdown-prompt-in', fmdp)
self.send_text('score-prompt-in', fsp)

View File

@@ -0,0 +1,120 @@
import sys
import os
current_directory = os.path.dirname(os.path.abspath(__file__))
sys.path.append(current_directory)
from flask_socketio import SocketIO, join_room, emit, Namespace
import agentscope
from agentscope.message import Msg
import os
import asyncio
import threading
import json
import configparser
from ...function_tools.function_manager import FunctionManager
import uuid
from ...utils import *
EMPTY_CHAPTER_CHAIN = [ Chapter(1, CHAPTER_FOCUS, "本章是未打开某个具体章节时的默认章节。", "处于本章节时不会有任何章节跳转。请作为一名经验丰富的算法教师,回答用户的问题。") ]
class ChatManager:
def __init__(self,user_uuid,ase_client,raw_markdown,raw_markdown_prompts,raw_score_prompts,max_iter = 5, app=None, socketio=None):
self.chapter_chain_now = -1
self.ase_client = ase_client
self.app = app
self.socketio = socketio
self.user_uuid = user_uuid
self.raw_markdown = raw_markdown
self.raw_markdown_prompts = raw_markdown_prompts
self.raw_score_prompts = raw_score_prompts
self.chapter_chain = load_chapters(raw_markdown, raw_markdown_prompts, raw_score_prompts)
self.function_manager = FunctionManager()
def next_chapter(self):
assert self.chapter_chain_now + 1 < len(self.chapter_chain), "chapter_chain_now out of range"
self.chapter_chain_now += 1
self.focus_chapter(self.chapter_chain_now)
def focus_chapter(self, chapter_index):
assert chapter_index < len(self.chapter_chain), "chapter_index out of range"
self.chapter_chain_now = chapter_index
self.chapter_chain[chapter_index].Focus()
self.ase_client.loadmarkdown(self.chapter_chain[chapter_index].chapter, self.chapter_chain[chapter_index].chapter_prompt, self.chapter_chain[chapter_index].score_prompt)
def message_pass(self, messagetype, message):
print("message_pass", self.user_uuid, messagetype, message)
with self.app.app_context():
try:
self.socketio.emit(messagetype, message, room=self.user_uuid, namespace='/agent')
except Exception as e:
print("message_pass",e)
def system_message(self, message):
with self.app.app_context():
try:
self.socketio.emit('system_message', message, room=self.user_uuid, namespace='/agent')
except Exception as e:
print("ERROR: system_message",e)
def save_chapter_memory(self, agent,course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal):
self.app.my_function.save_chapter_memory(self.user_uuid, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal)
def function_call(self, function_name, arg_function):
return self.function_manager.call_function(function_name, arg_function)
def change_language(self, id, language):
self.ase_client.send_text('language', language)
def sample_judge(self, id, bb):
self.function_manager.call_function('sample_judge', {'bb': bb})
with self.app.app_context():
try:
print(bb.get_active_file_reletive_path())
assert bb is not None and bb.active_file_path != "" , "no path specified"
if bb.get_active_file_reletive_path().endswith(".py"):
self.socketio.emit('terminal', {'data': f"python {bb.get_active_file_reletive_path()}"}, room=id, namespace='/vscode')
self.socketio.emit('system_message', "代码试运行尚在建设,推荐直接通过命令行执行!", room=id, namespace='/agent')
else:
self.socketio.emit('system_message', "代码试运行尚仅支持python文件", room=id, namespace='/agent')
except Exception as e:
print(e)
if (str(e) == "no path specified"):
self.socketio.emit("system_message", "未加载IDE文件同步请尝试重新打开IDE文件或刷新页面并确保插件已连接", room=id, namespace='/agent')
def judge(self, id, bb):
agent = self.agents[id]
with self.app.app_context():
try:
if (agent.chapter_chain[agent.chapter_chain_now].append_tools is not None and len(agent.chapter_chain[agent.chapter_chain_now].append_tools)):
for tool, tool_kwargs in agent.chapter_chain[agent.chapter_chain_now].append_tools:
if tool.__name__ == "judge":
print(bb.get_active_file_reletive_path())
assert bb is not None and bb.active_file_path != "" , "no path specified"
if bb.get_active_file_reletive_path().endswith(".py"):
# self.socketio.emit('terminal', {'data': f"python {bb.get_active_file_reletive_path()}"}, room=id, namespace='/vscode')
self.socketio.emit('system_message', "代码评测中,请稍后", room=id, namespace='/agent')
agent.function_call({'name':'judge','arguments':{'filepath': bb.get_active_file_reletive_path()}})
else:
self.socketio.emit('system_message', "代码评测尚仅支持python文件", room=id, namespace='/agent')
else:
with self.app.app_context():
self.socketio.emit("system_message", "本章学习无需评测", room=id, namespace='/agent')
else:
with self.app.app_context():
self.socketio.emit("system_message", "本章学习无需评测", room=id, namespace='/agent')
except Exception as e:
if (str(e) == "no path specified"):
self.socketio.emit("system_message", "未加载IDE文件同步请尝试重新打开IDE文件或刷新页面并确保插件已连接", room=id, namespace='/agent')

View File

@@ -29,7 +29,7 @@ course_list = CourseList()
user_uuid2UserClass = {}
user_uuid2ase_client = {}
user_uuid2chatmanager = {}
from AlgoriAgent.projects.algoriAgent.agent_manager import AgentManager
agent_manager = AgentManager()
def init_extensions(app):
@@ -43,7 +43,7 @@ def init_extensions(app):
)
cors.init_app(
app,
resources={r"/*": {"origins": app.config["VSCODE_WEB_URL"]}},
resources={r"/*": {"origins": "*"}},#app.config["VSCODE_WEB_URL"]}},
supports_credentials=True,
)
@@ -59,6 +59,7 @@ def init_extensions(app):
app.extensions["agent_manager"] = agent_manager
app.extensions["my_function"] = MyFunction()
app.extensions["user_uuid2ase_client"] = user_uuid2ase_client
app.extensions["user_uuid2chatmanager"] = user_uuid2chatmanager
mongo.init_app(app,uri=app.config["MONGO_URI"])
app.extensions["mongo"] = mongo

View File

@@ -0,0 +1,2 @@
from . import judge
from .function_manager import FunctionManager

View File

@@ -0,0 +1,18 @@
from typing import Callable
class FunctionManager:
def __init__(self):
self.function_caller = {}
self.function_predifine_args = {}
def add_function(self, function:Callable, predifine_args:dict):
self.function_caller[function.__name__] = function
self.function_predifine_args[function.__name__] = predifine_args
def get_function(self, function_name:str):
return self.function_caller[function_name]
def get_function_predifine_args(self, function_name:str):
return self.function_predifine_args[function_name]
def call_function(self, function_name:str, args:dict):
return self.function_caller[function_name]( **args, **self.function_predifine_args[function_name])

View File

@@ -0,0 +1,74 @@
import os
from ..models.function import FunctionResponse, FunctionStatus
def judge(filepath:str, name: str, course_id: str, lesson_id: str, root_path:str):
"""Call this method to judge the student's solution after they have completed the problem.
Args:
filepath (`str`): The path to the file containing the student's solution.
name (`str`): The name of the problem.
course_id (`str`): The id of the course.
lesson_id (`str`): The id of the lesson.
root_path (`str`): The root path of the user's workspace project.
Returns:
Report `tuple(int,str)`: The report of the student's solution.
"""
# 从books/code_tests/name/中获取所有.in文件
directory = 'books/code_tests/'+course_id+'/'+name
# 如果目录不存在,报错
if not os.path.exists(directory):
status = FunctionStatus.FAILED
return FunctionResponse("judge", status, f"The name {name} is not found.")
files = os.listdir(directory)
in_files = [file for file in files if file.endswith('.in')]
save_dir = root_path
Report = ""
passed_num=0
failed_num=0
erroroutput = ""
exceptoutput=""
for file in in_files:
file_path = os.path.join(save_dir, f"_{name}.out")
if os.path.exists(file_path):
os.remove(file_path)
with open(file_path, 'w') as ff:
ff.write("")
cmd = "cat " + os.path.join(directory, file) + " | " + "python " + os.path.join(root_path, filepath) +" > " + os.path.join(save_dir, f"_{name}.out")
os.system(cmd)
# 比较结果
re = ""
if compare_file(os.path.join(save_dir, f"_{name}.out"), os.path.join(directory, file.replace(".in", ".out"))):
re = f"Passed {file}"
passed_num += 1
else:
re = f"Failed {file}"
failed_num += 1
with open(os.path.join(directory, file.replace(".in", ".out")),'r') as f: exceptoutput = f.read()
with open(os.path.join(save_dir, f"_{name}.out"),'r') as f: erroroutput = f.read()
Report = Report + re + "\n"
os.remove(os.path.join(save_dir, f"_{name}.out"))
score = int (100 * passed_num / (passed_num + failed_num))
status = FunctionStatus.SUCCESS
return FunctionResponse("judge", status, f"评测得分为 {score}, 在 {passed_num + failed_num} 个测试用例中通过了 {passed_num}个。最后一个错误样例期望输出:'{exceptoutput}',但你的输出:'{erroroutput}")
def compare_file(path1:str, path2:str):
"""
Compare two files and return true if they are the same.
"""
with open(path1, 'r') as f1, open(path2, 'r') as f2:
# 逐行比较
print('-------------------COMPARE-------------------------')
for line1, line2 in zip(f1, f2):
print(line1.strip(), "||",line2.strip())
if line1.strip() != line2.strip():
return False
return True
judge_tools = [judge]

View File

@@ -0,0 +1,11 @@
from pydantic import BaseModel
from enum import Enum
from typing import Optional
FunctionStatus = Enum("FunctionStatus", ["SUCCESS", "ERROR"])
class FunctionResponse(BaseModel):
name: str
status: FunctionStatus
message: str = ""
args: Optional[dict] = None

View File

@@ -2,10 +2,13 @@
import json
from flask import current_app, request, session
from flask_socketio import Namespace, join_room, leave_room, emit
from ..function_tools import judge
from ..services.memory_service import save_chapter_memory_by_uuid
from ..services.backboard_service import realtime_response
from ..services.markdown_service import load_full_markdown_file
from ..extension_ase.ase_client import ASEngineClient
from ..extension_ase.ase_client import HSAEngineClient, ChatManager
class VSCodeNamespace(Namespace):
def on_login(self,data):
@@ -50,32 +53,32 @@ class AgentNamespace(Namespace):
user_id = uuid2username[user_uuid]
session['user_uuid'] = user_uuid
print(f'User connected with session user_uuid: {user_uuid}')
user_uuid2chatmanager = ex["user_uuid2chatmanager"]
user_uuid2ase_client = ex["user_uuid2ase_client"]
user_uuid2ase_client[user_uuid] = ASEngineClient(current_app.config["ASE_ENGINE_URL"], current_app.config["ASE_ENGINE_NAMESPACE"])
user_uuid2ase_client[user_uuid] = HSAEngineClient(current_app.config["ASE_ENGINE_URL"], current_app.config["ASE_ENGINE_NAMESPACE"])
user_uuid2ase_client[user_uuid].connect()
user_uuid2ase_client[user_uuid].register_route_with_entry(
route='dialog',
callback=self.receive_ase_dialog,
entry=self, # 传你的 Namespace 对象
init_data={'room': user_uuid} # 想传啥都可以
entry=self,
init_data={'room': user_uuid}
)
fmd,fmdp,fsp = load_full_markdown_file(course_id, chapter_name, lesson_name)
# 从markdown、markdown_prompts、score_prompts中各读取数据folder.md并进行new_agent
user_uuid2chatmanager[user_uuid] = ChatManager(user_uuid, user_uuid2ase_client[user_uuid], fmd, fmdp, fsp, max_iter=5, app=current_app, socketio=self)
chatmanager = user_uuid2chatmanager[user_uuid]
chatmanager.function_manager.add_function(judge, {'course_id': course_id, 'lesson_name': lesson_name, 'root_path': f'../../study/{user_id}/{course_id}/{chapter_name}/{lesson_name}'})
user_uuid2ase_client[user_uuid].loadmarkdown(fmd, fmdp, fsp)
user_uuid, agent = agent_manager.new_agent(course_id, lesson_name, fmd, fmdp, fsp, id=user_uuid,
root_path=f'../../study/{user_id}/{course_id}/{chapter_name}/{lesson_name}')
print(user_uuid)
join_room(user_uuid, namespace='/agent') # 将该用户加入以user_id为名的room
backboard_manager.add_backboard(user_uuid, user_id, course_id, lesson_name, root_path=f'../../study/{user_id}/{course_id}/{chapter_name}/{lesson_name}')
chatmanager.focus_chapter(0)
def on_language(self, language):
ex = current_app.extensions
agent_manager = ex["agent_manager"]
uuid2username = ex["uuid2username"]
uuid = session.get('user_uuid')
user_id = uuid2username[uuid]
agent_manager.change_language(uuid, language)
print(f"Language changed to: {language}")
def on_message(self, data):
print(f"Message from client: {data}")
@@ -89,7 +92,6 @@ class AgentNamespace(Namespace):
if (type(data)==str):
data = json.loads(data)
if data['type'] == 'text':
# res = agent_manager.invoke(uuid, data['data'], backboard_manager.get_backboard(uuid).get_info_prompt())
user_uuid2ase_client[uuid].send_text('dialog', data['data'])
# print('=*='*20)
# print(res.content)
@@ -102,12 +104,11 @@ class AgentNamespace(Namespace):
agent_manager.function_call(uuid, data['data'])
def receive_ase_dialog(client_entry: ASEngineClient, namespace_entry: Namespace, data, init_data):
print(f"Received from ASEngine: {data}")
# 直接使用 entry也就是你的 Namespace 对象)
def receive_ase_dialog(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data):
namespace_entry.emit('message', data['data'], room=init_data['room'], namespace='/agent')
def receive_ase_function(client_entry: HSAEngineClient, namespace_entry: Namespace, data, init_data):
namespace_entry.emit('request_function', data['data'], room=init_data['room'], namespace='/agent')
def on_initiative(self,data):
print("User active function call")

View File

@@ -4,7 +4,7 @@ let system_message_idx=0
document.addEventListener('DOMContentLoaded', function() {
data = window.appData;
console.log(data);
socket = io('ws://localhost:5551/agent',{
socket = io('wss://localhost:5551/agent',{
query:{
user_uuid:data.user_uuid,
folder:data.folder

View File

@@ -0,0 +1 @@
from .chapterUtil import *

View File

@@ -0,0 +1,159 @@
from typing import Callable, Any
from AlgoriAgent.projects.algoriAgent.tools.judge_tools import judge
CHAPTER_FINISH = 0
CHAPTER_FOCUS = 1
CHAPTER_LATTER = 2
CHAPTER_FAILED = 3
def tool_name_to_tool(tool_name_list):
tools = []
for tool_name in tool_name_list:
if tool_name == "":
continue
if tool_name == "judge":
tools.append(judge)
return tools
def tool_name_to_tool_with_args(tool_name_list, tool_args_list) -> list[tuple[Callable, dict]]:
tools = []
for tool_name, tool_args in zip(tool_name_list, tool_args_list):
if tool_name == "":
continue
if tool_name == "judge":
tools.append((judge, {"name": tool_args[0]}))
return tools
class Chapter():
def __init__(self, No = 1, focus = 2,title="", chapter = "", chapter_prompt = "",
score_prompt = "", append_tools : list[Callable[..., Any], dict] = None) -> None:
'''
No : 序号
focus : 0: Finished, 1: Focus, 2: Latter, 3: Failed
title : 子章节标题
chapter : 教案子章节内容
chapter_prompt : 教案的提示
score_prompt : 评测标准
append_tools : 追加工具函数
'''
self.No = No
self.focus = focus
self.chapter = chapter
self.chapter_prompt = chapter_prompt
self.score_prompt = score_prompt
self.append_tools = append_tools
self.memory = None
self.title =title
def GetChapter(self):
if self.focus == CHAPTER_FINISH: f = "(Finished Chapter)"
elif self.focus == CHAPTER_FOCUS: f = "(Your Now Chapter)"
elif self.focus == CHAPTER_LATTER: f = "(Ignore for Latter Chapter)"
elif self.focus == CHAPTER_FAILED: f = "(Failed Chapter)"
# des = f"{f} Chapter {self.No}: {self.chapter if self.focus else 'Hidden for further study.'}"
des = f"{f} Chapter {self.No}: "
if self.focus == CHAPTER_FINISH or self.focus == CHAPTER_FAILED: des += 'Hidden due to finished.'
if self.focus == CHAPTER_LATTER: des += 'Hidden for further study.'
if self.focus == CHAPTER_FOCUS:
des+=self.chapter
des+='\n'
des+='Here are some concrete instructions:\n'
des+=self.chapter_prompt+'\n'
return des
def Finished(self, successful: bool = True):
if successful: self.focus = 0
else: self.focus = 3
def Focus(self):
self.focus = 1
def load_chapters(markdown, markdown_prompt, score_prompt):
markdown_list = markdown.split("\n")
markdown_prompt_list = markdown_prompt.split("\n")
score_prompt_list = score_prompt.split("\n")
# 获取 H1 标题
title = ""
for line in markdown_list:
if line.startswith("# "):
title = line[2:]
break
# 对于 H3 标题 构造每一个 Chapter
# 首先找到所有的 H3 标题
chapter_dict = {}
chapter_sequence = []
for line in markdown_list:
if line.startswith("### "):
chapter_name = line[4:]
chapter_dict[chapter_name] = {}
chapter_sequence.append(chapter_name)
# 将 H3 标题 和 其对应的内容 构造成一个 Chapter
h3_name = ""
content = ""
for i in range(len(markdown_list)):
if markdown_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["markdown"] = content
h3_name = markdown_list[i][4:]
content = ""
continue
if h3_name != "":
content += markdown_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["markdown"] = content
h3_name = ""
content = ""
require_tools = []
require_tools_args = []
for i in range(len(markdown_prompt_list)):
if markdown_prompt_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["markdown_prompt"] = content
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool_with_args(require_tools, require_tools_args)
h3_name = markdown_prompt_list[i][4:]
content = ""
require_tools=[]
require_tools_args = []
continue
if h3_name != "":
if markdown_prompt_list[i].startswith("_require_tools"):
require_tools.append(markdown_prompt_list[i].split("=")[1].strip().split(",")[0])
require_tools_args.append((markdown_prompt_list[i].split("=")[1].strip().split(",")[1:]))
continue
content += markdown_prompt_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["markdown_prompt"] = content
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool_with_args(require_tools, require_tools_args)
h3_name = ""
content = ""
for i in range(len(score_prompt_list)):
if score_prompt_list[i].startswith("### "):
if(h3_name != ""):
chapter_dict[h3_name]["score_prompt"] = content
h3_name = score_prompt_list[i][4:]
content = ""
continue
if h3_name != "":
content += score_prompt_list[i]+"\n"
if(h3_name != ""):
chapter_dict[h3_name]["score_prompt"] = content
chapter_chain = []
No = 1
print (chapter_dict)
for chapter_name in chapter_sequence:
chapter_chain.append(Chapter( No, CHAPTER_LATTER, chapter_name, chapter_dict[chapter_name]["markdown"], chapter_dict[chapter_name]["markdown_prompt"], chapter_dict[chapter_name]["score_prompt"],chapter_dict[chapter_name]["require_tools"]))
No+=1
return chapter_chain

View File

@@ -62,7 +62,10 @@ def desktop_nouser(course_id, chapter_name, lesson_name):
@bp.route("/vscode_data", methods=["POST"])
def vscode_data():
data = request.get_json(force=True)
config = data.get("config") or {}
realtime_response(config, data) # 调用服务层逻辑
return jsonify({"status": "success", "received": data})
# data = request.get_json(force=True)
# config = data.get("config") or {}
# realtime_response(config, data) # 调用服务层逻辑
# return jsonify({"status": "success", "received": data})
return jsonify({"status": "success", "received": "success"})

22
Html/server.crt Normal file
View File

@@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDoTCCAokCFF/OMLJof3ypmpQCK3zGNpJ15pDBMA0GCSqGSIb3DQEBCwUAMIGM
MQswCQYDVQQGEwJVUzESMBAGA1UECAwJU29tZVN0YXRlMREwDwYDVQQHDAhTb21l
Q2l0eTEQMA4GA1UECgwHU29tZU9yZzERMA8GA1UECwwIU29tZVVuaXQxEjAQBgNV
BAMMCWxvY2FsaG9zdDEdMBsGCSqGSIb3DQEJARYOeW91ckBlbWFpbC5jb20wHhcN
MjUwOTEwMTYzMTU4WhcNMjYwOTEwMTYzMTU4WjCBjDELMAkGA1UEBhMCVVMxEjAQ
BgNVBAgMCVNvbWVTdGF0ZTERMA8GA1UEBwwIU29tZUNpdHkxEDAOBgNVBAoMB1Nv
bWVPcmcxETAPBgNVBAsMCFNvbWVVbml0MRIwEAYDVQQDDAlsb2NhbGhvc3QxHTAb
BgkqhkiG9w0BCQEWDnlvdXJAZW1haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA0BFtyncXSrEEXn0iCSumufiJMwIf+qmes3tv8db05yHPjReD
gDvwzSmm4+5lDo/EkMK64gOXAoqy7nO/40OyEnIOBbWrUg6M9gPM6F9DEJZsM9Ae
M/1lkwnsJ3IgbKSf2uw+riwBAfnnClDWvEkIqH96d4352yQba694k7Zn936NnzWd
ROYaLXqy4HoR2UYOM4nzaPq9EoANLsPNgftQjWMDVhsAnt7FtDnvT+86wB4KWKXA
QVIw2QmjrhaeajpL2N4xG5SQxb6mlFaZKw/sCHAo5JqmRhQ9p7CAE47DYHIDC+Sp
GHaJJKrbA81RLU1iTLtmsYrpRHNp+S2f1nJODQIDAQABMA0GCSqGSIb3DQEBCwUA
A4IBAQAhagxrnwPkVpdM6tqaaEE4xGdWxrIuipBNXTbtYd/8WOhVDDaLWjMo0vG4
70Pgq+HJ166XdL00ZTj4UfcC1Ls5qRLkfimb/Rz59BfK0iE8QVEKt6yfJWUD6HuI
y2tl9hqUJrW1OTcMgEOV6Dg+RX3VpDcDML5SJ17r9IqaaB0HAV9IVGt+jK1ZzUBp
h0iQUrH3+x9xR5x41Vz2TKgeFuxYnwqGPhCdRdDX2prYWDMV4awAkUvx/5oyCw3q
juisnWoyzFw1WMiA9Hl+29XL1k5X1QE9gLrW3qvhB/OnrRaYK3sfHZMSYSrr+CDJ
+bT/JOuQBdTSsc4VCLphezh8C1Sy
-----END CERTIFICATE-----

28
Html/server.key Normal file
View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQEW3KdxdKsQRe
fSIJK6a5+IkzAh/6qZ6ze2/x1vTnIc+NF4OAO/DNKabj7mUOj8SQwrriA5cCirLu
c7/jQ7IScg4FtatSDoz2A8zoX0MQlmwz0B4z/WWTCewnciBspJ/a7D6uLAEB+ecK
UNa8SQiof3p3jfnbJBtrr3iTtmf3fo2fNZ1E5hoterLgehHZRg4zifNo+r0SgA0u
w82B+1CNYwNWGwCe3sW0Oe9P7zrAHgpYpcBBUjDZCaOuFp5qOkvY3jEblJDFvqaU
VpkrD+wIcCjkmqZGFD2nsIATjsNgcgML5KkYdokkqtsDzVEtTWJMu2axiulEc2n5
LZ/Wck4NAgMBAAECggEAE3JAOyc0mj//eF9PR4vOCjKUNsa7kL9lUZa3UziJF3MT
BWJNtuCjSbbbXhE2s7eJzRJ4yffrl2AO3MzHrJNz+K0H6iOyY+Rv60GsAd8paEr5
c5bqGRIqpKVNmNrd9Jl8RpyZjR4YEq8LF206bKA80Ba+A5+AMH7oQIEcDrOCdbXc
m9JYo0yiehyZyVtPZJjw70uAstJ+n/gFhIh1B7kSaIbKCPLmHHph19jnWAEXKVLX
Hzb7Q5BhcCqiON7RJ3kDlomGiMmS/xuqjdbsruNcdg2ze/iAA2Gvw7Y52Q4/q69e
y/yxupS5FeFz9YjrmSJavws8ttZTVb1Y2W3ZoUFFZwKBgQDq5ZZXsWieslAq6x6S
MAwIz4NGAlui721QBG8aFipMr3B/wi9PJHqNkkCywYnm26xjkkpRsiPlWkbnfbeB
7mw6t1Yo58qZPNCxVKpl8cFX76mzhNyPEjI7b2N7fmiwJZQx6QXEQ98XEWeWrPVg
7E5SN4/aw6EScxC/Qlwf9CgjLwKBgQDiws4R14/+K4lv9omdobs+AX2TqZ/XugQR
zClLWgHziPhj+lzJlbuFqM6h+aFKETTCPRlJGjDy42R+FrU4rtfhEmILaEyuox02
0xHfNdJ7bziQSiRrOqNmpKIhZvt71ozh0XuRBwFMQOwFI5nnCvbyGWRep9ChMw8m
czFqhb1DgwKBgQCLu6vl2smLrjN2dIupFx/xldBXs0tj794tPZYCBLGBENRxi8is
4dxtn1URgYRRathwGzROyRQFeeC4ENc7WePUQf/lMY4Z/k1/UAhVwKztbMqc2iqC
iaaMKMUbT6VjM9emoSInEOEDTf07awRFdg1ZZ2gSEVIeMYkC3a0D7TB7TQKBgQCD
KPBuq4OTHXWSeERjE9As7knHZj6ZVfPSo4djGT21so0RrxeKVfwwNFLIp44ePFOK
4jJE8UxMwTA4KkRJ8//UJIDnXj20aY6VToKw2/3R/aP2+ZuVFka7MRDCR0HBAHle
iH9zhFzA0XBzDIOReusZX4yJn4FyLAlgURLNLWwqpwKBgB/hh4aM0oUcl3KNnvMY
Vd/PFTiGgwfTebOpIAMBiyquAjDyto659M6N2ZE5kMipvfX+mqaV0ZLTw1rKzVhp
qvUVtFXlZipkb6yCFnkLvvoC+FJrobKK0cqZ3KlIcfx3hkt07ykmcqd8Q2rV7qMT
8/exXLRwkWtd0Tfq52ZLH+Yw
-----END PRIVATE KEY-----