diff --git a/.dockerignore b/.dockerignore new file mode 100755 index 0000000000000000000000000000000000000000..637e2d1cdb045dd9be1a9ef921c4ef57d654d9c9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,4 @@ +.vscode +.idea + +Dockerfile \ No newline at end of file diff --git a/.env.micro b/.env.micro new file mode 100755 index 0000000000000000000000000000000000000000..6b77ac90737f35d79c48aca1f1641f44110ca939 --- /dev/null +++ b/.env.micro @@ -0,0 +1,2 @@ +VITE_BASE_URL=/copilot/ +VITE_MICRO_ROUTER_URL=/eulercopilot/ \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000000000000000000000000000000000000..4b7c8707953847c9b01c76273fff3604a969aea9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.env +.env.development +package-lock.json + +*.tsbuildinfo + +.eslintignore +.eslintrc.cjs +.prettierignore +.prettierrc + +.gitee/ +.npmrc +.pnpm-lock.yaml diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100755 index 0000000000000000000000000000000000000000..a54eff92e87fbce476cb4030be64a16a1bd43d26 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "arrowParens": "avoid", + "printWidth": 120, + "semi": true, + "singleQuote": true, + "tabWidth": 2 +} diff --git a/Dockerfile b/Dockerfile new file mode 100755 index 0000000000000000000000000000000000000000..2de6833d9d7bd55cf2387ce5f3ba637cca1d8d98 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM node:18.18.2-alpine as Builder + +RUN mkdir -p /opt/eulerCopilot-web +WORKDIR /opt/eulerCopilot-web +COPY . . + +RUN npm install pnpm -g --registry=https://registry.npmmirror.com && \ + pnpm install --registry=https://registry.npmmirror.com && \ + pnpm run build + +FROM nginx:1.21.5 + +COPY --from=Builder /opt/eulerCopilot-web/dist /usr/share/nginx/html +RUN chmod -R 755 /usr/share/nginx/html +COPY --from=Builder /opt/eulerCopilot-web/deploy/dev/euler_copilot.conf /etc/nginx/conf.d/ + +ENV RUN_USER nginx +ENV RUN_GROUP nginx + +EXPOSE 8080 + +ENTRYPOINT [ "nginx", "-g", "daemon off;" ] \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100755 index 0000000000000000000000000000000000000000..a590d20ddcf068926e9be91b1f4fc91512a03cd3 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,40 @@ +node { + echo "拉取代码仓库" + checkout scm + + def REPO = scm.getUserRemoteConfigs()[0].getUrl().tokenize('/').last().split("\\.")[0] + def BRANCH = scm.branches[0].name.split("/")[1] + def BUILD = sh(script: 'git rev-parse --short HEAD', returnStdout: true).trim() + + withCredentials([string(credentialsId: "host", variable: "HOST")]) { + echo "构建当前分支Docker Image镜像" + docker.withRegistry("http://${HOST}:30000", "dockerAuth") { + def image = docker.build("${HOST}:30000/${REPO}:${BUILD}", "-f ./deploy/prod/Dockerfile .") + image.push() + image.push("${BRANCH}") + } + + def remote = [:] + remote.name = "machine" + remote.host = "${HOST}" + withCredentials([usernamePassword(credentialsId: "ssh", usernameVariable: 'sshUser', passwordVariable: 'sshPass')]) { + remote.user = sshUser + remote.password = sshPass + } + remote.allowAnyHosts = true + + echo "清除构建缓存" + sshCommand remote: remote, command: "sh -c \"docker rmi ${HOST}:30000/${REPO}:${BUILD} || true\";" + sshCommand remote: remote, command: "sh -c \"docker rmi ${REPO}:${BUILD} || true\";" + sshCommand remote: remote, command: "sh -c \"docker rmi ${REPO}:${BRANCH} || true\";" + sshCommand remote: remote, command: "sh -c \"docker image prune -f || true\";"; + sshCommand remote: remote, command: "sh -c \"docker builder prune -f || true\";"; + sshCommand remote: remote, command: "sh -c \"k3s crictl rmi --prune || true\";"; + + echo "重新部署" + withCredentials([usernamePassword(credentialsId: "dockerAuth", usernameVariable: 'dockerUser', passwordVariable: 'dockerPass')]) { + sshCommand remote: remote, command: "sh -c \"cd /home/registry/registry-cli; python3 ./registry.py -l ${dockerUser}:${dockerPass} -r http://${HOST}:30000 --delete --keep-tags 'master' '0001' '330-feature' '430-feature' 'local_deploy' || true\";" + } + sshCommand remote: remote, command: "sh -c \"kubectl -n euler-copilot set image deployment/web-deploy web=${HOST}:30000/${REPO}:${BUILD}\";" + } +} diff --git a/LICENSE/LICENSE b/LICENSE/LICENSE new file mode 100755 index 0000000000000000000000000000000000000000..f6c26977bbb993b180afd759658dcf5ea6619cd0 --- /dev/null +++ b/LICENSE/LICENSE @@ -0,0 +1,194 @@ +木兰宽松许可证,第2版 + +木兰宽松许可证,第2版 + +2020年1月 http://license.coscl.org.cn/MulanPSL2 + +您对“软件”的复制、使用、修改及分发受木兰宽松许可证,第2版(“本许可证”)的如下条款的约束: + +0. 定义 + +“软件” 是指由“贡献”构成的许可在“本许可证”下的程序和相关文档的集合。 + +“贡献” 是指由任一“贡献者”许可在“本许可证”下的受版权法保护的作品。 + +“贡献者” 是指将受版权法保护的作品许可在“本许可证”下的自然人或“法人实体”。 + +“法人实体” 是指提交贡献的机构及其“关联实体”。 + +“关联实体” 是指,对“本许可证”下的行为方而言,控制、受控制或与其共同受控制的机构,此处的控制是 +指有受控方或共同受控方至少50%直接或间接的投票权、资金或其他有价证券。 + +1. 授予版权许可 + +每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的版权许可,您可 +以复制、使用、修改、分发其“贡献”,不论修改与否。 + +2. 授予专利许可 + +每个“贡献者”根据“本许可证”授予您永久性的、全球性的、免费的、非独占的、不可撤销的(根据本条规定 +撤销除外)专利许可,供您制造、委托制造、使用、许诺销售、销售、进口其“贡献”或以其他方式转移其“贡 +献”。前述专利许可仅限于“贡献者”现在或将来拥有或控制的其“贡献”本身或其“贡献”与许可“贡献”时的“软 +件”结合而将必然会侵犯的专利权利要求,不包括对“贡献”的修改或包含“贡献”的其他结合。如果您或您的“ +关联实体”直接或间接地,就“软件”或其中的“贡献”对任何人发起专利侵权诉讼(包括反诉或交叉诉讼)或 +其他专利维权行动,指控其侵犯专利权,则“本许可证”授予您对“软件”的专利许可自您提起诉讼或发起维权 +行动之日终止。 + +3. 无商标许可 + +“本许可证”不提供对“贡献者”的商品名称、商标、服务标志或产品名称的商标许可,但您为满足第4条规定 +的声明义务而必须使用除外。 + +4. 分发限制 + +您可以在任何媒介中将“软件”以源程序形式或可执行形式重新分发,不论修改与否,但您必须向接收者提供“ +本许可证”的副本,并保留“软件”中的版权、商标、专利及免责声明。 + +5. 免责声明与责任限制 + +“软件”及其中的“贡献”在提供时不带任何明示或默示的担保。在任何情况下,“贡献者”或版权所有者不对 +任何人因使用“软件”或其中的“贡献”而引发的任何直接或间接损失承担责任,不论因何种原因导致或者基于 +何种法律理论,即使其曾被建议有此种损失的可能性。 + +6. 语言 + +“本许可证”以中英文双语表述,中英文版本具有同等法律效力。如果中英文版本存在任何冲突不一致,以中文 +版为准。 + +条款结束 + +如何将木兰宽松许可证,第2版,应用到您的软件 + +如果您希望将木兰宽松许可证,第2版,应用到您的新软件,为了方便接收者查阅,建议您完成如下三步: + +1, 请您补充如下声明中的空白,包括软件名、软件的首次发表年份以及您作为版权人的名字; + +2, 请您在软件包的一级目录下创建以“LICENSE”为名的文件,将整个许可证文本放入该文件中; + +3, 请将如下声明文本放入每个源文件的头部注释中。 + +Copyright (c) [Year] [name of copyright holder] +[Software Name] is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. + +Mulan Permissive Software License,Version 2 + +Mulan Permissive Software License,Version 2 (Mulan PSL v2) + +January 2020 http://license.coscl.org.cn/MulanPSL2 + +Your reproduction, use, modification and distribution of the Software shall +be subject to Mulan PSL v2 (this License) with the following terms and +conditions: + +0. Definition + +Software means the program and related documents which are licensed under +this License and comprise all Contribution(s). + +Contribution means the copyrightable work licensed by a particular +Contributor under this License. + +Contributor means the Individual or Legal Entity who licenses its +copyrightable work under this License. + +Legal Entity means the entity making a Contribution and all its +Affiliates. + +Affiliates means entities that control, are controlled by, or are under +common control with the acting entity under this License, ‘control’ means +direct or indirect ownership of at least fifty percent (50%) of the voting +power, capital or other securities of controlled or commonly controlled +entity. + +1. Grant of Copyright License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to you a perpetual, worldwide, royalty-free, non-exclusive, +irrevocable copyright license to reproduce, use, modify, or distribute its +Contribution, with modification or not. + +2. Grant of Patent License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to you a perpetual, worldwide, royalty-free, non-exclusive, +irrevocable (except for revocation under this Section) patent license to +make, have made, use, offer for sale, sell, import or otherwise transfer its +Contribution, where such patent license is only limited to the patent claims +owned or controlled by such Contributor now or in future which will be +necessarily infringed by its Contribution alone, or by combination of the +Contribution with the Software to which the Contribution was contributed. +The patent license shall not apply to any modification of the Contribution, +and any other combination which includes the Contribution. If you or your +Affiliates directly or indirectly institute patent litigation (including a +cross claim or counterclaim in a litigation) or other patent enforcement +activities against any individual or entity by alleging that the Software or +any Contribution in it infringes patents, then any patent license granted to +you under this License for the Software shall terminate as of the date such +litigation or activity is filed or taken. + +3. No Trademark License + +No trademark license is granted to use the trade names, trademarks, service +marks, or product names of Contributor, except as required to fulfill notice +requirements in section 4. + +4. Distribution Restriction + +You may distribute the Software in any medium with or without modification, +whether in source or executable forms, provided that you provide recipients +with a copy of this License and retain copyright, patent, trademark and +disclaimer statements in the Software. + +5. Disclaimer of Warranty and Limitation of Liability + +THE SOFTWARE AND CONTRIBUTION IN IT ARE PROVIDED WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED. IN NO EVENT SHALL ANY CONTRIBUTOR OR +COPYRIGHT HOLDER BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING, BUT NOT +LIMITED TO ANY DIRECT, OR INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING +FROM YOUR USE OR INABILITY TO USE THE SOFTWARE OR THE CONTRIBUTION IN IT, NO +MATTER HOW IT’S CAUSED OR BASED ON WHICH LEGAL THEORY, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGES. + +6. Language + +THIS LICENSE IS WRITTEN IN BOTH CHINESE AND ENGLISH, AND THE CHINESE VERSION +AND ENGLISH VERSION SHALL HAVE THE SAME LEGAL EFFECT. IN THE CASE OF +DIVERGENCE BETWEEN THE CHINESE AND ENGLISH VERSIONS, THE CHINESE VERSION +SHALL PREVAIL. + +END OF THE TERMS AND CONDITIONS + +How to Apply the Mulan Permissive Software License,Version 2 +(Mulan PSL v2) to Your Software + +To apply the Mulan PSL v2 to your work, for easy identification by +recipients, you are suggested to complete following three steps: + +i. Fill in the blanks in following statement, including insert your software +name, the year of the first publication of your software, and your name +identified as the copyright owner; + +ii. Create a file named "LICENSE" which contains the whole context of this +License in the first directory of your software package; + +iii. Attach the statement to the appropriate annotated syntax at the +beginning of each source file. + +Copyright (c) [Year] [name of copyright holder] +[Software Name] is licensed under Mulan PSL v2. +You can use this software according to the terms and conditions of the Mulan +PSL v2. +You may obtain a copy of Mulan PSL v2 at: + http://license.coscl.org.cn/MulanPSL2 +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO +NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +See the Mulan PSL v2 for more details. diff --git a/deploy/dev/euler_copilot.conf b/deploy/dev/euler_copilot.conf new file mode 100755 index 0000000000000000000000000000000000000000..60e428ad965e9cbd6a1579085ee12245c67fbf37 --- /dev/null +++ b/deploy/dev/euler_copilot.conf @@ -0,0 +1,77 @@ +server { + listen 8080; + server_name localhost; + charset utf-8; + + add_header X-XSS-Protection "1; mode=block"; + add_header Referrer-Policy "no-referrer"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: base64;"; + add_header Cache-Control "no-cache,no-store,must-revalidate"; + add_header Pragma no-cache; + add_header Expires 0; + # limit_conn limitperip 10; + + if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE)$) { + return 444; + } + + location ~ /\. { + deny all; + return 404; + } + + location ~ ^(?:(?!/static)).*\.(js|css|ico|png|jpg|eot|svg|ttf|woff|html|txt|pdf)$ { + root /usr/share/nginx/html; + expires 30d; + } + + location / { + proxy_set_header X-Real-IP $remote_addr; + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + if (!-e $request_filename){ + rewrite ^(.*)$ /index.html last; + } + } + + location /api/health_check { + deny all; + return 404; + } + + location /api/ { + proxy_set_header X-Real-IP $remote_addr; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: base64;"; + add_header Cache-Control "no-cache,no-store,must-revalidate"; + add_header Pragma no-cache; + add_header Expires 0; + proxy_buffering off; + error_page 404 = @not_found; + + proxy_pass https://rag.test.osinfra.cn/; + } + + location @not_found { + root /usr/share/nginx/html; + rewrite ^ /404.html break; + } + + + error_page 401 402 403 405 406 407 413 414 /error.html; + error_page 404 /404.html; + error_page 500 501 502 503 504 505 /error.html; + + location = /404.html { + root /usr/share/nginx/html; + } + + location = /error.html { + root /usr/share/nginx/html; + } + + } diff --git a/deploy/k8s/web-config.yaml b/deploy/k8s/web-config.yaml new file mode 100755 index 0000000000000000000000000000000000000000..bef88739a3e53730af007c38277df6fd6f7d45e1 --- /dev/null +++ b/deploy/k8s/web-config.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: web-config + namespace: euler-copilot +data: + .env: | + #配置文件,参考deploy/prod/.env.example +# dhparam.pem: | #SSL秘钥协商配置文件 +# -----BEGIN DH PARAMETERS----- +# MIICCAKCAgEA29KHqU1FaHYwJkQiPjpKV7bCV3cV6dvMtRpr1g3I6Q7AcDUGEDk0 +# 1XV01HWJShymeN2WuKkLR28Es6N9kvu/3t3Po+PagHNXJg7RTlPgyeOM/dckUiWe +# 86+CpRM8iHKkgoh2JARswTVRHmiwBcVK/GDL2cPTT6Q3YihZZg4GIcIxqQ2Pn8EF +# ZH3XkLiaOqQpfUF/j20qhi4n8/Zktb3EIJxxBHk06cWVaGvClv6uN6trxIp65Kk5 +# SMMeG//AulZ08Wj4tCqWnktn1ZqfgBXBPB0nSankMHVz2iX8dSJerST8BUPo56VB +# 9eimEKR19Em7hCJOZrl8rBwkZy2w8LFz0UDNaDRLqL+X16KszwRYKmNtEQKwJOjT +# qWJV0UAUAjPkTbvbtzK0JANT+EWvaESjsmh05+Y5Ezoi69422FNfKhxi4veUN8A+ +# Gfvqve+lqUTwiWESh6zmNpFn4ifvJQZc+QeNUYUSAoYz4n5rKP7CL9rBql2PMSqV +# QSc9gG/mhSXrgFPM7kN8lG5QUzj78Ove0+DwKD7agMIKS5RI3e8ecmq8XNtLecLW +# iU/UMbwLsmNzhV6tL0YoMHmkqHfPHyBAbzK9Pk5TG3MPcCE4Sb8TkO1TR3blWbcC +# xU09fcDYBfNsH6B8MngEAxtXTLTORwJZVpt1k0rl607WnoXIGXBpQqsCAQI= +# -----END DH PARAMETERS----- + server.crt: | + #SSL证书 + server.key: | + #SSL私钥 + pass.txt: | + #SSL私钥密码 \ No newline at end of file diff --git a/deploy/k8s/web-deployment.yaml b/deploy/k8s/web-deployment.yaml new file mode 100755 index 0000000000000000000000000000000000000000..ae5b566c429b3e5541d460bfa7d0295a7b499241 --- /dev/null +++ b/deploy/k8s/web-deployment.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: web-deploy + namespace: euler-copilot + labels: + app: web +spec: + replicas: 1 + selector: + matchLabels: + app: web + template: + metadata: + labels: + app: web + spec: + automountServiceAccountToken: false + securityContext: + fsGroup: 1001 + containers: + - name: web + image: #Web镜像地址 + imagePullPolicy: Always + ports: + - containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: 8080 + scheme: HTTP #依据实际可改为HTTPS协议 + failureThreshold: 5 + initialDelaySeconds: 60 + periodSeconds: 90 + env: + - name: TZ + value: Asia/Shanghai + volumeMounts: + - mountPath: /config + name: web-config-volume + - mountPath: /var/lib/nginx/tmp + name: web-tmp + - mountPath: /home/eulercopilot/.env + name: web-env-volume + subPath: .env + # 使用SSL证书的时候,需要挂载证书文件 +# - mountPath: /config/pass.txt +# name: web-env-volume +# subPath: pass.txt +# - mountPath: /config/server.key +# name: web-env-volume +# subPath: server.key +# - mountPath: /config/server.crt +# name: web-env-volume +# subPath: server.crt +# - mountPath: /config/dhparam.pem +# name: web-env-volume +# subPath: dhparam.pem + securityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + runAsUser: 1001 + runAsGroup: 1001 + runAsNonRoot: true + allowPrivilegeEscalation: false +# resources: +# limits: +# memory: 1024Mi +# cpu: 500m + restartPolicy: Always + volumes: + - name: web-config-volume + emptyDir: + medium: Memory + - name: web-env-volume + configMap: + name: web-config + - name: web-tmp + emptyDir: + medium: Memory diff --git a/deploy/k8s/web-ingress.yaml b/deploy/k8s/web-ingress.yaml new file mode 100755 index 0000000000000000000000000000000000000000..e04c813966669f008ef6689ccb50a79ee8263740 --- /dev/null +++ b/deploy/k8s/web-ingress.yaml @@ -0,0 +1,14 @@ +apiVersion: traefik.containo.us/v1alpha1 +kind: IngressRoute +metadata: + name: web-ingress + namespace: euler-copilot +spec: + entryPoints: + - websecure + routes: + - match: PathPrefix(`/`) + kind: Rule + services: + - name: web-service + port: 8080 \ No newline at end of file diff --git a/deploy/k8s/web-service.yaml b/deploy/k8s/web-service.yaml new file mode 100755 index 0000000000000000000000000000000000000000..29689dc7d7706bfcc90334068d9b56c9df01d69d --- /dev/null +++ b/deploy/k8s/web-service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: web-service + namespace: euler-copilot +spec: + type: ClusterIP #暴露端口,可使用NodePort,也可使用Ingress + selector: + app: web + ports: + - port: 8080 + targetPort: 8080 + #nodePort: 30000 diff --git a/deploy/prod/.env.example b/deploy/prod/.env.example new file mode 100755 index 0000000000000000000000000000000000000000..5caa64d19da806ba7c7cf5a514d95bded7d3fb27 --- /dev/null +++ b/deploy/prod/.env.example @@ -0,0 +1,5 @@ +PROD= +SSL_ENABLE_FLAG= +DOMAIN_LIMIT_ENABLE_FLAG= +SERVER_NAME= +FRAMEWORK_URL= \ No newline at end of file diff --git a/deploy/prod/Dockerfile b/deploy/prod/Dockerfile new file mode 100755 index 0000000000000000000000000000000000000000..30cdccdba093498438b710bfc026f5698fe8874b --- /dev/null +++ b/deploy/prod/Dockerfile @@ -0,0 +1,54 @@ +FROM node:18.18.2-alpine +WORKDIR /opt/eulerCopilot-web + +COPY . . +RUN sed -i 's/qa-robot-openeuler/euler-copilot-master/g' .env && \ + npm install pnpm -g --registry=https://registry.npmmirror.com && \ + pnpm install --registry=https://registry.npmmirror.com && \ + pnpm run build + + +FROM openeuler/openeuler:22.03-lts-sp1 + +ENV TZ Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \ + echo $TZ > /etc/timezone + +RUN sed -i 's|repo.openeuler.org|mirrors.nju.edu.cn/openeuler|g' /etc/yum.repos.d/openEuler.repo && \ + sed -i '/metalink/d' /etc/yum.repos.d/openEuler.repo && \ + sed -i '/metadata_expire/d' /etc/yum.repos.d/openEuler.repo && \ + yum update -y && \ + yum install -y nginx shadow-utils passwd gettext && \ + yum clean all && \ + groupadd -g 1001 eulercopilot && \ + useradd -m -u 1001 -g eulercopilot -s /sbin/nologin eulercopilot && \ + passwd -l eulercopilot + +COPY --from=0 /opt/eulerCopilot-web/dist /usr/share/nginx/html +COPY --from=0 /opt/eulerCopilot-web/public /usr/share/nginx/html +COPY --from=0 /opt/eulerCopilot-web/deploy/prod/nginx.conf.tmpl /home/eulercopilot/nginx.conf.tmpl +COPY --from=0 /opt/eulerCopilot-web/deploy/prod/start.sh /home/eulercopilot/start.sh + +RUN sed -i 's/umask 002/umask 027/g' /etc/bashrc && \ + sed -i 's/umask 022/umask 027/g' /etc/bashrc && \ + chown -R eulercopilot:eulercopilot /usr/share/nginx && \ + chown -R eulercopilot:eulercopilot /var/log/nginx && \ + chown -R eulercopilot:eulercopilot /var/lib/nginx && \ + chown -R eulercopilot:eulercopilot /etc/nginx && \ + chmod -R 750 /var/log/nginx && \ + find /var/log/nginx -type f -exec chmod 640 {} + && \ + chmod -R 500 /var/lib/nginx && \ + chmod -R 500 /usr/share/nginx && \ + chmod -R 500 /etc/nginx && \ + find /var/log/nginx -type f -exec chmod 400 {} + + +RUN yum remove -y gdb-gdbserver && \ + sh -c "find /usr /etc \( -name *yum* -o -name *dnf* -o -name *vi* -o -name *sqlite* -o -name *python* \) -exec rm -rf {} + || true" && \ + sh -c "find /usr /etc \( -name ps -o -name top \) -exec rm -rf {} + || true" + +EXPOSE 8080 + +USER eulercopilot +WORKDIR /home/eulercopilot + +ENTRYPOINT [ "bash", "./start.sh" ] diff --git a/deploy/prod/nginx.conf.tmpl b/deploy/prod/nginx.conf.tmpl new file mode 100755 index 0000000000000000000000000000000000000000..c0575d23611d0304fe47175765949768399adc14 --- /dev/null +++ b/deploy/prod/nginx.conf.tmpl @@ -0,0 +1,156 @@ +worker_processes auto; +worker_rlimit_nofile 4096; +error_log ${ERROR_FILE} info; +pid ${PID_FILE}; + +include /usr/share/nginx/modules/*.conf; + +events { + use epoll; + worker_connections 1024; +} + +http { + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log ${LOG_FILE} main; + + autoindex off; + server_tokens off; + + port_in_redirect off; + absolute_redirect off; + + client_header_buffer_size 1k; + large_client_header_buffers 4 8k; + client_body_buffer_size 16K; + client_max_body_size 2M; + + client_header_timeout 15s; + client_body_timeout 15s; + client_body_in_file_only off; + + keepalive_timeout 500s; + send_timeout 25s; + + limit_conn_zone $binary_remote_addr zone=limitperip:10m; + limit_req_zone $binary_remote_addr zone=ratelimit:10m rate=1000r/s; + + proxy_hide_header X-Powered-By; + proxy_request_buffering off; + + sendfile on; + tcp_nopush on; + tcp_nodelay on; + types_hash_max_size 4096; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + gzip on; + gzip_min_length 1k; + gzip_buffers 4 16k; + gzip_comp_level 5; + gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/javascript application/x-httpd-php application/json; + gzip_vary on; + + include /etc/nginx/conf.d/*.conf; + + server { + listen 8080 ${SSL_ENABLE} default_server; + server_name ${SERVER_NAME}; + charset utf-8; + + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options nosniff; + add_header Referrer-Policy "no-referrer"; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; always"; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: base64;"; + add_header Cache-Control "no-cache,no-store,must-revalidate"; + add_header X-Accel-Buffering no; + add_header Pragma no-cache; + add_header Expires 0; + + limit_conn limitperip 10; + + ${SSL_SETTINGS} + + resolver 8.8.8.8 8.8.4.4 valid=60s; + resolver_timeout 5s; + + ${DOMAIN_LIMIT} + + if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE)$) { + return 444; + } + + location ~ /\. { + deny all; + return 404; + } + + location ~ ^(?:(?!/static)).*\.(js|css|ico|png|jpg|eot|svg|ttf|woff|html|txt|pdf)$ { + root /usr/share/nginx/html; + expires 30d; + } + + location / { + limit_req zone=ratelimit burst=5 nodelay; + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + if (!-e $request_filename){ + return 404; + } + } + + location /login { + limit_req zone=ratelimit burst=5 nodelay; + root /usr/share/nginx/html; + try_files $uri $uri/ /index.html; + } + + location /api/health_check { + deny all; + return 404; + } + + location /api/ { + proxy_set_header X-Forwarded-For $http_x_real_ip; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Content-Type-Options nosniff; + add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'"; + add_header Cache-Control "no-cache,no-store,must-revalidate"; + add_header X-Accel-Buffering no; + add_header Pragma no-cache; + add_header Expires 0; + proxy_buffering off; + proxy_intercept_errors on; + error_page 404 /404.html; + limit_req zone=ratelimit burst=5 nodelay; + proxy_read_timeout 500s; + proxy_connect_timeout 500s; + + proxy_pass ${FRAMEWORK_URL}/api/; + } + + error_page 401 402 403 405 406 407 413 414 /error.html; + error_page 404 /404.html; + error_page 500 501 502 503 504 505 /error.html; + + location = /404 { + return 404; + } + + location = /404.html { + root /usr/share/nginx/html; + internal; + } + + location = /error.html { + root /usr/share/nginx/html; + internal; + } + } +} diff --git a/deploy/prod/start.sh b/deploy/prod/start.sh new file mode 100755 index 0000000000000000000000000000000000000000..f49d1b8c39b468b05ac8f83560a5c1c36f16f33c --- /dev/null +++ b/deploy/prod/start.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +export $(cat .env | xargs) + +domain_limit=" + if (\$http_Host !~ ${SERVER_NAME} $) { + return 403; + } +" + +ssl_settings=" + ssl_session_tickets off; + ssl_session_timeout 5m; + ssl_session_cache shared:SSL:10m; + + ssl_certificate /config/server.crt; + ssl_certificate_key /config/server.key; + ssl_password_file /config/pass.txt; + ssl_dhparam /config/dhparam.pem; + ssl_ecdh_curve auto; + ssl_protocols TLSv1.2; + ssl_ciphers \"ECDHE-RSA-AES256-GCM-SHA384\"; + ssl_prefer_server_ciphers on; + ssl_stapling on; + ssl_stapling_verify on; +" + +if [[ -v SSL_ENABLE_FLAG ]]; then + export SSL_ENABLE=ssl + export SSL_SETTINGS=$ssl_settings +else + export SSL_ENABLE="" +fi + +if [[ -v PROD ]]; then + export ERROR_FILE="/dev/stderr" + export LOG_FILE="/dev/stdout" + export PID_FILE="/var/lib/nginx/tmp/nginx.pid" +else + export ERROR_FILE="/var/log/nginx/error.log" + export LOG_FILE="/var/log/nginx/access.log" + export PID_FILE="/var/log/nginx/nginx.pid" +fi + +if [[ -v DOMAIN_LIMIT_ENABLE_FLAG ]]; then + export DOMAIN_LIMIT=$domain_limit +else + export DOMAIN_LIMIT="" +fi + +bash -c "envsubst '\${SERVER_NAME} \${SSL_ENABLE} \${SSL_SETTINGS} \${ERROR_FILE} \${LOG_FILE} \${PID_FILE} \${DOMAIN_LIMIT} \${FRAMEWORK_URL}' < nginx.conf.tmpl > /config/nginx.conf" + +nginx -c /config/nginx.conf -g "daemon off;" \ No newline at end of file diff --git a/env.d.ts b/env.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..2f2faacf07ada6ae3a24a65082f6de5c3b323499 --- /dev/null +++ b/env.d.ts @@ -0,0 +1,31 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +/// +declare interface Window { + onHtmlEventDispatch: (); +} + +declare interface ImportMetaEnv { + readonly VITE_LOGIN_CALLBACK_URL: string; + readonly VITE_LOGOUT_CALLBACK_URL: string; + + readonly VITE_BASE_PROXY_URL: string; + readonly VITE_BASE_URL: string; + readonly VITE_USER_TYPE: string; + + readonly VITE_OEPKG_URL: string; + readonly VITE_PKGSHIP_URL: string; + readonly VITE_MIRROR_URL: string; + readonly VITE_GUIDANCE_URL: string; + readonly VITE_FORUM_URL: string; + readonly VITE_MAIL_URL: string; + readonly VITE_BULLETIN_URL: string; + readonly VITE_HISS_URL: string; +} diff --git a/index.html b/index.html new file mode 100755 index 0000000000000000000000000000000000000000..9416bf39e880ee36fe7b3a700378e509e59ac8f2 --- /dev/null +++ b/index.html @@ -0,0 +1,19 @@ + + + + + + + openEuler Copilot System-问答机器人 + + + + +
+ + + diff --git a/lib/opendesign2-2.0.11.tgz b/lib/opendesign2-2.0.11.tgz new file mode 100755 index 0000000000000000000000000000000000000000..d11dc18e426343687bb9e278be323cb20b058db0 Binary files /dev/null and b/lib/opendesign2-2.0.11.tgz differ diff --git a/package.json b/package.json new file mode 100755 index 0000000000000000000000000000000000000000..70ad47468924c4f79bd349ed969516b64462820c --- /dev/null +++ b/package.json @@ -0,0 +1,49 @@ +{ + "name": "euler-copilot-web", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "dev:micro": "vite --mode micro", + "build": "vite build", + "build:micro": "vite build --mode micro", + "preview": "vite preview", + "lint": "eslint . --fix --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --ignore-path .gitignore", + "format": "prettier --write src/" + }, + "engines": { + "node": ">= 18.18.2" + }, + "dependencies": { + "@computing/opendesign2": "file:lib\\opendesign2-2.0.11.tgz", + "axios": "1.6.1", + "dayjs": "1.11.9", + "echarts": "^5.4.3", + "element-plus": "2.3.12", + "highlight.js": "11.4.0", + "marked": "4.3", + "pinia": "2.1.6", + "sass": "1.62.0", + "typescript": "4.9.5", + "vite": "4.1.5", + "vue": "3.3.4", + "vue-echarts": "^7.0.3", + "vue-i18n": "^9.14.0", + "vue-router": "4.2.4", + "xss": "1.0.14", + "xterm": "4.17.0", + "xterm-addon-attach": "0.5.0", + "xterm-addon-fit": "0.6.0" + }, + "devDependencies": { + "@types/node": "20.5.9", + "@typescript-eslint/eslint-plugin": "5.51.0", + "@typescript-eslint/parser": "5.51.0", + "@vitejs/plugin-vue": "4.0.0", + "eslint": "8.34.0", + "eslint-plugin-vue": "9.9.0", + "prettier": "2.8.4", + "vite-plugin-qiankun": "^1.0.15" + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100755 index 0000000000000000000000000000000000000000..d1b5935f6a7c0356c3d888a98b9ac5d5049d3db6 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2454 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@computing/opendesign2': + specifier: file:lib\opendesign2-2.0.11.tgz + version: file:lib/opendesign2-2.0.11.tgz(element-plus@2.3.12(vue@3.3.4)) + axios: + specifier: 1.6.1 + version: 1.6.1 + dayjs: + specifier: 1.11.9 + version: 1.11.9 + echarts: + specifier: ^5.4.3 + version: 5.4.3 + element-plus: + specifier: 2.3.12 + version: 2.3.12(vue@3.3.4) + highlight.js: + specifier: 11.4.0 + version: 11.4.0 + marked: + specifier: '4.3' + version: 4.3.0 + pinia: + specifier: 2.1.6 + version: 2.1.6(typescript@4.9.5)(vue@3.3.4) + sass: + specifier: 1.62.0 + version: 1.62.0 + typescript: + specifier: 4.9.5 + version: 4.9.5 + vite: + specifier: 4.1.5 + version: 4.1.5(@types/node@20.5.9)(sass@1.62.0) + vue: + specifier: 3.3.4 + version: 3.3.4 + vue-echarts: + specifier: ^7.0.3 + version: 7.0.3(@vue/runtime-core@3.3.4)(echarts@5.4.3)(vue@3.3.4) + vue-i18n: + specifier: ^9.14.0 + version: 9.14.0(vue@3.3.4) + vue-router: + specifier: 4.2.4 + version: 4.2.4(vue@3.3.4) + xss: + specifier: 1.0.14 + version: 1.0.14 + xterm: + specifier: 4.17.0 + version: 4.17.0 + xterm-addon-attach: + specifier: 0.5.0 + version: 0.5.0(xterm@4.17.0) + xterm-addon-fit: + specifier: 0.6.0 + version: 0.6.0(xterm@4.17.0) + devDependencies: + '@types/node': + specifier: 20.5.9 + version: 20.5.9 + '@typescript-eslint/eslint-plugin': + specifier: 5.51.0 + version: 5.51.0(@typescript-eslint/parser@5.51.0(eslint@8.34.0)(typescript@4.9.5))(eslint@8.34.0)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 5.51.0 + version: 5.51.0(eslint@8.34.0)(typescript@4.9.5) + '@vitejs/plugin-vue': + specifier: 4.0.0 + version: 4.0.0(vite@4.1.5(@types/node@20.5.9)(sass@1.62.0))(vue@3.3.4) + eslint: + specifier: 8.34.0 + version: 8.34.0 + eslint-plugin-vue: + specifier: 9.9.0 + version: 9.9.0(eslint@8.34.0) + prettier: + specifier: 2.8.4 + version: 2.8.4 + vite-plugin-qiankun: + specifier: ^1.0.15 + version: 1.0.15(typescript@4.9.5)(vite@4.1.5(@types/node@20.5.9)(sass@1.62.0)) + +packages: + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.6': + resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.25.6': + resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} + engines: {node: '>=6.9.0'} + + '@computing/opendesign2@file:lib/opendesign2-2.0.11.tgz': + resolution: {integrity: sha512-/VMvfeygSenedb7zHH3SvUgQqH5RgC1w9p0/XkDVRVYSge4Nv9PkwTxdf/HHlqs8LeH1WQwKNRJWU9/+n4vaTw==, tarball: file:lib/opendesign2-2.0.11.tgz} + version: 2.0.11 + peerDependencies: + element-plus: '>=2.2.34' + + '@ctrl/tinycolor@3.6.1': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + + '@element-plus/icons-vue@2.3.1': + resolution: {integrity: sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==} + peerDependencies: + vue: ^3.2.0 + + '@esbuild/android-arm64@0.16.17': + resolution: {integrity: sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.16.17': + resolution: {integrity: sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.16.17': + resolution: {integrity: sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.16.17': + resolution: {integrity: sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.16.17': + resolution: {integrity: sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.16.17': + resolution: {integrity: sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.16.17': + resolution: {integrity: sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.16.17': + resolution: {integrity: sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.16.17': + resolution: {integrity: sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.16.17': + resolution: {integrity: sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.16.17': + resolution: {integrity: sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.16.17': + resolution: {integrity: sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.16.17': + resolution: {integrity: sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.16.17': + resolution: {integrity: sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.16.17': + resolution: {integrity: sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.16.17': + resolution: {integrity: sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.16.17': + resolution: {integrity: sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.16.17': + resolution: {integrity: sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.16.17': + resolution: {integrity: sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.16.17': + resolution: {integrity: sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.16.17': + resolution: {integrity: sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.16.17': + resolution: {integrity: sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint/eslintrc@1.4.1': + resolution: {integrity: sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@floating-ui/core@1.6.7': + resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==} + + '@floating-ui/dom@1.6.10': + resolution: {integrity: sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==} + + '@floating-ui/utils@0.2.7': + resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@intlify/core-base@9.14.0': + resolution: {integrity: sha512-zJn0imh9HIsZZUtt9v8T16PeVstPv6bP2YzlrYJwoF8F30gs4brZBwW2KK6EI5WYKFi3NeqX6+UU4gniz5TkGg==} + engines: {node: '>= 16'} + + '@intlify/message-compiler@9.14.0': + resolution: {integrity: sha512-sXNsoMI0YsipSXW8SR75drmVK56tnJHoYbPXUv2Cf9lz6FzvwsosFm6JtC1oQZI/kU+n7qx0qRrEWkeYFTgETA==} + engines: {node: '>= 16'} + + '@intlify/shared@9.14.0': + resolution: {integrity: sha512-r+N8KRQL7LgN1TMTs1A2svfuAU0J94Wu9wWdJVJqYsoMMLIeJxrPjazihfHpmJqfgZq0ah3Y9Q4pgWV2O90Fyg==} + engines: {node: '>= 16'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@sxzz/popperjs-es@2.11.7': + resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.7': + resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} + + '@types/node@20.5.9': + resolution: {integrity: sha512-PcGNd//40kHAS3sTlzKB9C9XL4K0sTup8nbG5lC14kzEteTNuAFh9u5nA0o5TWnSG2r/JNPRXFVcHJIIeRlmqQ==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/web-bluetooth@0.0.16': + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + + '@typescript-eslint/eslint-plugin@5.51.0': + resolution: {integrity: sha512-wcAwhEWm1RgNd7dxD/o+nnLW8oH+6RK1OGnmbmkj/GGoDPV1WWMVP0FXYQBivKHdwM1pwii3bt//RC62EriIUQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@5.51.0': + resolution: {integrity: sha512-fEV0R9gGmfpDeRzJXn+fGQKcl0inIeYobmmUWijZh9zA7bxJ8clPhV9up2ZQzATxAiFAECqPQyMDB4o4B81AaA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@5.51.0': + resolution: {integrity: sha512-gNpxRdlx5qw3yaHA0SFuTjW4rxeYhpHxt491PEcKF8Z6zpq0kMhe0Tolxt0qjlojS+/wArSDlj/LtE69xUJphQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/type-utils@5.51.0': + resolution: {integrity: sha512-QHC5KKyfV8sNSyHqfNa0UbTbJ6caB8uhcx2hYcWVvJAZYJRBo5HyyZfzMdRx8nvS+GyMg56fugMzzWnojREuQQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@5.51.0': + resolution: {integrity: sha512-SqOn0ANn/v6hFn0kjvLwiDi4AzR++CBZz0NV5AnusT2/3y32jdc0G4woXPWHCumWtUXZKPAS27/9vziSsC9jnw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/typescript-estree@5.51.0': + resolution: {integrity: sha512-TSkNupHvNRkoH9FMA3w7TazVFcBPveAAmb7Sz+kArY6sLT86PA5Vx80cKlYmd8m3Ha2SwofM1KwraF24lM9FvA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@5.51.0': + resolution: {integrity: sha512-76qs+5KWcaatmwtwsDJvBk4H76RJQBFe+Gext0EfJdC3Vd2kpY2Pf//OHHzHp84Ciw0/rYoGTDnIAr3uWhhJYw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/visitor-keys@5.51.0': + resolution: {integrity: sha512-Oh2+eTdjHjOFjKA27sxESlA87YPSOJafGCR0md5oeMdh1ZcCfAGCIOL216uTBAkAIptvLIfKQhl7lHxMJet4GQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@vitejs/plugin-vue@4.0.0': + resolution: {integrity: sha512-e0X4jErIxAB5oLtDqbHvHpJe/uWNkdpYV83AOG2xo2tEVSzCzewgJMtREZM30wXnM5ls90hxiOtAuVU6H5JgbA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + vue: ^3.2.25 + + '@vue/compiler-core@3.3.4': + resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} + + '@vue/compiler-dom@3.3.4': + resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} + + '@vue/compiler-sfc@3.3.4': + resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} + + '@vue/compiler-ssr@3.3.4': + resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} + + '@vue/devtools-api@6.6.3': + resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==} + + '@vue/reactivity-transform@3.3.4': + resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} + + '@vue/reactivity@3.3.4': + resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} + + '@vue/runtime-core@3.3.4': + resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} + + '@vue/runtime-dom@3.3.4': + resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} + + '@vue/server-renderer@3.3.4': + resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} + peerDependencies: + vue: 3.3.4 + + '@vue/shared@3.3.4': + resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} + + '@vueuse/core@9.13.0': + resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} + + '@vueuse/metadata@9.13.0': + resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} + + '@vueuse/shared@9.13.0': + resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + axios@1.6.1: + resolution: {integrity: sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0: + resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} + engines: {node: '>=18.17'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssfilter@0.0.10: + resolution: {integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + dayjs@1.11.9: + resolution: {integrity: sha512-QvzAURSbQ0pKdIye2txOzNaHmxtUBXerpY0FJsFXUMKbIZeFm5ht1LS/jFsrncjnmtv8HsG0W2g6c0zUjZWmpA==} + + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + echarts@5.4.3: + resolution: {integrity: sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==} + + element-plus@2.3.12: + resolution: {integrity: sha512-fAWpbKCyt+l1dsqSNPOs/F/dBN4Wp5CGAyxbiS5zqDwI4q3QPM+LxLU2h3GUHMIBtMGCvmsG98j5HPMkTKkvcA==} + peerDependencies: + vue: ^3.2.0 + + encoding-sniffer@0.2.0: + resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + esbuild@0.16.17: + resolution: {integrity: sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==} + engines: {node: '>=12'} + hasBin: true + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-vue@9.9.0: + resolution: {integrity: sha512-YbubS7eK0J7DCf0U2LxvVP7LMfs6rC6UltihIgval3azO3gyDwEGVgsCMe1TmDiEkl6GdMKfRpaME6QxIYtzDQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-utils@3.0.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + + eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.34.0: + resolution: {integrity: sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + highlight.js@11.4.0: + resolution: {integrity: sha512-nawlpCBCSASs7EdvZOYOYVkJpGmAOKMYZgZtUqSRqodZE0GRVcFKwo1RcpeOemqh9hyttTdd5wDBwHkuSyUfnA==} + engines: {node: '>=12.0.0'} + + htmlparser2@9.1.0: + resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + immutable@4.3.7: + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-sdsl@4.4.2: + resolution: {integrity: sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash-unified@1.0.3: + resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==} + peerDependencies: + '@types/lodash-es': '*' + lodash: '*' + lodash-es: '*' + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + + memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-wheel-es@1.2.0: + resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pinia@2.1.6: + resolution: {integrity: sha512-bIU6QuE5qZviMmct5XwCesXelb5VavdOWKWaB17ggk++NUwQWWbP5YnsONTk3b752QkW9sACiR81rorpeOMSvQ==} + peerDependencies: + '@vue/composition-api': ^1.4.0 + typescript: '>=4.4.4' + vue: ^2.6.14 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + typescript: + optional: true + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss@8.4.43: + resolution: {integrity: sha512-gJAQVYbh5R3gYm33FijzCZj7CHyQ3hWMgJMprLUlIYqCwTeZhBQ19wp0e9mA25BUbEvY5+EXuuaAjqQsrBxQBQ==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@2.8.4: + resolution: {integrity: sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==} + engines: {node: '>=10.13.0'} + hasBin: true + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup@3.29.4: + resolution: {integrity: sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass@1.62.0: + resolution: {integrity: sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==} + engines: {node: '>=14.0.0'} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + undici@6.19.8: + resolution: {integrity: sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g==} + engines: {node: '>=18.17'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vite-plugin-qiankun@1.0.15: + resolution: {integrity: sha512-0QB0Wr8Eu/LGcuJAfuNXDb7BAFDszo3GCxq4bzgXdSFAlK425u1/UGMxaDEBVA1uPFrLsZPzig83Ufdfl6J45A==} + peerDependencies: + typescript: '>=4' + vite: '>=2' + + vite@4.1.5: + resolution: {integrity: sha512-zJ0RiVkf61kpd7O+VtU6r766xgnTaIknP/lR6sJTZq3HtVJ3HGnTo5DaJhTUtYoTyS/CQwZ6yEVdc/lrmQT7dQ==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vue-demi@0.13.11: + resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-echarts@7.0.3: + resolution: {integrity: sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==} + peerDependencies: + '@vue/runtime-core': ^3.0.0 + echarts: ^5.5.1 + vue: ^2.7.0 || ^3.1.1 + peerDependenciesMeta: + '@vue/runtime-core': + optional: true + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + vue-i18n@9.14.0: + resolution: {integrity: sha512-LxmpRuCt2rI8gqU+kxeflRZMQn4D5+4M3oP3PWZdowW/ePJraHqhF7p4CuaME52mUxdw3Mmy2yAUKgfZYgCRjA==} + engines: {node: '>= 16'} + peerDependencies: + vue: ^3.0.0 + + vue-router@4.2.4: + resolution: {integrity: sha512-9PISkmaCO02OzPVOMq2w82ilty6+xJmQrarYZDkjZBfl4RvYAlt4PKnEX21oW4KTtWfa9OuO/b3qk1Od3AEdCQ==} + peerDependencies: + vue: ^3.2.0 + + vue@3.3.4: + resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xss@1.0.14: + resolution: {integrity: sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==} + engines: {node: '>= 0.10.0'} + hasBin: true + + xterm-addon-attach@0.5.0: + resolution: {integrity: sha512-L6ThPjF/fVt+gJS2+2h2rEEAXNxIRmCU8/RCM6rYR08K9GtPiHmYcnpRT7WNJf31yFLpWVA8dKcItfP3C0ZKlA==} + deprecated: This package is now deprecated. Move to @xterm/addon-attach instead. + peerDependencies: + xterm: ^4.0.0 + + xterm-addon-fit@0.6.0: + resolution: {integrity: sha512-9/7A+1KEjkFam0yxTaHfuk9LEvvTSBi0PZmEkzJqgafXPEXL9pCMAVV7rB09sX6ATRDXAdBpQhZkhKj7CGvYeg==} + deprecated: This package is now deprecated. Move to @xterm/addon-fit instead. + peerDependencies: + xterm: ^5.0.0 + + xterm@4.17.0: + resolution: {integrity: sha512-WGXlIHvLvZKtwMdFaL6kUwp+c9abd2Pcakp/GmuefBuOtGCu9fP9tBDPKyL/A17N+5tt44EYk3YsBbvkPBubMw==} + deprecated: This package is now deprecated. Move to @xterm/xterm instead. + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zrender@5.4.4: + resolution: {integrity: sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==} + +snapshots: + + '@babel/helper-string-parser@7.24.8': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/parser@7.25.6': + dependencies: + '@babel/types': 7.25.6 + + '@babel/types@7.25.6': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@computing/opendesign2@file:lib/opendesign2-2.0.11.tgz(element-plus@2.3.12(vue@3.3.4))': + dependencies: + element-plus: 2.3.12(vue@3.3.4) + + '@ctrl/tinycolor@3.6.1': {} + + '@element-plus/icons-vue@2.3.1(vue@3.3.4)': + dependencies: + vue: 3.3.4 + + '@esbuild/android-arm64@0.16.17': + optional: true + + '@esbuild/android-arm@0.16.17': + optional: true + + '@esbuild/android-x64@0.16.17': + optional: true + + '@esbuild/darwin-arm64@0.16.17': + optional: true + + '@esbuild/darwin-x64@0.16.17': + optional: true + + '@esbuild/freebsd-arm64@0.16.17': + optional: true + + '@esbuild/freebsd-x64@0.16.17': + optional: true + + '@esbuild/linux-arm64@0.16.17': + optional: true + + '@esbuild/linux-arm@0.16.17': + optional: true + + '@esbuild/linux-ia32@0.16.17': + optional: true + + '@esbuild/linux-loong64@0.16.17': + optional: true + + '@esbuild/linux-mips64el@0.16.17': + optional: true + + '@esbuild/linux-ppc64@0.16.17': + optional: true + + '@esbuild/linux-riscv64@0.16.17': + optional: true + + '@esbuild/linux-s390x@0.16.17': + optional: true + + '@esbuild/linux-x64@0.16.17': + optional: true + + '@esbuild/netbsd-x64@0.16.17': + optional: true + + '@esbuild/openbsd-x64@0.16.17': + optional: true + + '@esbuild/sunos-x64@0.16.17': + optional: true + + '@esbuild/win32-arm64@0.16.17': + optional: true + + '@esbuild/win32-ia32@0.16.17': + optional: true + + '@esbuild/win32-x64@0.16.17': + optional: true + + '@eslint/eslintrc@1.4.1': + dependencies: + ajv: 6.12.6 + debug: 4.3.6 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@floating-ui/core@1.6.7': + dependencies: + '@floating-ui/utils': 0.2.7 + + '@floating-ui/dom@1.6.10': + dependencies: + '@floating-ui/core': 1.6.7 + '@floating-ui/utils': 0.2.7 + + '@floating-ui/utils@0.2.7': {} + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.6 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@intlify/core-base@9.14.0': + dependencies: + '@intlify/message-compiler': 9.14.0 + '@intlify/shared': 9.14.0 + + '@intlify/message-compiler@9.14.0': + dependencies: + '@intlify/shared': 9.14.0 + source-map-js: 1.2.0 + + '@intlify/shared@9.14.0': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@sxzz/popperjs-es@2.11.7': {} + + '@types/json-schema@7.0.15': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.7 + + '@types/lodash@4.17.7': {} + + '@types/node@20.5.9': {} + + '@types/semver@7.5.8': {} + + '@types/web-bluetooth@0.0.16': {} + + '@typescript-eslint/eslint-plugin@5.51.0(@typescript-eslint/parser@5.51.0(eslint@8.34.0)(typescript@4.9.5))(eslint@8.34.0)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/parser': 5.51.0(eslint@8.34.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/type-utils': 5.51.0(eslint@8.34.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.51.0(eslint@8.34.0)(typescript@4.9.5) + debug: 4.3.6 + eslint: 8.34.0 + grapheme-splitter: 1.0.4 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + regexpp: 3.2.0 + semver: 7.6.3 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@5.51.0(eslint@8.34.0)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/typescript-estree': 5.51.0(typescript@4.9.5) + debug: 4.3.6 + eslint: 8.34.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@5.51.0': + dependencies: + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/visitor-keys': 5.51.0 + + '@typescript-eslint/type-utils@5.51.0(eslint@8.34.0)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.51.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.51.0(eslint@8.34.0)(typescript@4.9.5) + debug: 4.3.6 + eslint: 8.34.0 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@5.51.0': {} + + '@typescript-eslint/typescript-estree@5.51.0(typescript@4.9.5)': + dependencies: + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/visitor-keys': 5.51.0 + debug: 4.3.6 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.3 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@5.51.0(eslint@8.34.0)(typescript@4.9.5)': + dependencies: + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 5.51.0 + '@typescript-eslint/types': 5.51.0 + '@typescript-eslint/typescript-estree': 5.51.0(typescript@4.9.5) + eslint: 8.34.0 + eslint-scope: 5.1.1 + eslint-utils: 3.0.0(eslint@8.34.0) + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@5.51.0': + dependencies: + '@typescript-eslint/types': 5.51.0 + eslint-visitor-keys: 3.4.3 + + '@vitejs/plugin-vue@4.0.0(vite@4.1.5(@types/node@20.5.9)(sass@1.62.0))(vue@3.3.4)': + dependencies: + vite: 4.1.5(@types/node@20.5.9)(sass@1.62.0) + vue: 3.3.4 + + '@vue/compiler-core@3.3.4': + dependencies: + '@babel/parser': 7.25.6 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.3.4': + dependencies: + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + + '@vue/compiler-sfc@3.3.4': + dependencies: + '@babel/parser': 7.25.6 + '@vue/compiler-core': 3.3.4 + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-ssr': 3.3.4 + '@vue/reactivity-transform': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.11 + postcss: 8.4.43 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.3.4': + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/shared': 3.3.4 + + '@vue/devtools-api@6.6.3': {} + + '@vue/reactivity-transform@3.3.4': + dependencies: + '@babel/parser': 7.25.6 + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.11 + + '@vue/reactivity@3.3.4': + dependencies: + '@vue/shared': 3.3.4 + + '@vue/runtime-core@3.3.4': + dependencies: + '@vue/reactivity': 3.3.4 + '@vue/shared': 3.3.4 + + '@vue/runtime-dom@3.3.4': + dependencies: + '@vue/runtime-core': 3.3.4 + '@vue/shared': 3.3.4 + csstype: 3.1.3 + + '@vue/server-renderer@3.3.4(vue@3.3.4)': + dependencies: + '@vue/compiler-ssr': 3.3.4 + '@vue/shared': 3.3.4 + vue: 3.3.4 + + '@vue/shared@3.3.4': {} + + '@vueuse/core@9.13.0(vue@3.3.4)': + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.13.0 + '@vueuse/shared': 9.13.0(vue@3.3.4) + vue-demi: 0.14.10(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@9.13.0': {} + + '@vueuse/shared@9.13.0(vue@3.3.4)': + dependencies: + vue-demi: 0.14.10(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + acorn-jsx@5.3.2(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + async-validator@4.2.5: {} + + asynckit@0.4.0: {} + + axios@1.6.1: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + callsites@3.1.0: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + encoding-sniffer: 0.2.0 + htmlparser2: 9.1.0 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + parse5-parser-stream: 7.1.2 + undici: 6.19.8 + whatwg-mimetype: 4.0.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@2.20.3: {} + + concat-map@0.0.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + cssfilter@0.0.10: {} + + csstype@3.1.3: {} + + dayjs@1.11.9: {} + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + deep-is@0.1.4: {} + + delayed-stream@1.0.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + echarts@5.4.3: + dependencies: + tslib: 2.3.0 + zrender: 5.4.4 + + element-plus@2.3.12(vue@3.3.4): + dependencies: + '@ctrl/tinycolor': 3.6.1 + '@element-plus/icons-vue': 2.3.1(vue@3.3.4) + '@floating-ui/dom': 1.6.10 + '@popperjs/core': '@sxzz/popperjs-es@2.11.7' + '@types/lodash': 4.17.7 + '@types/lodash-es': 4.17.12 + '@vueuse/core': 9.13.0(vue@3.3.4) + async-validator: 4.2.5 + dayjs: 1.11.9 + escape-html: 1.0.3 + lodash: 4.17.21 + lodash-es: 4.17.21 + lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21) + memoize-one: 6.0.0 + normalize-wheel-es: 1.2.0 + vue: 3.3.4 + transitivePeerDependencies: + - '@vue/composition-api' + + encoding-sniffer@0.2.0: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + entities@4.5.0: {} + + esbuild@0.16.17: + optionalDependencies: + '@esbuild/android-arm': 0.16.17 + '@esbuild/android-arm64': 0.16.17 + '@esbuild/android-x64': 0.16.17 + '@esbuild/darwin-arm64': 0.16.17 + '@esbuild/darwin-x64': 0.16.17 + '@esbuild/freebsd-arm64': 0.16.17 + '@esbuild/freebsd-x64': 0.16.17 + '@esbuild/linux-arm': 0.16.17 + '@esbuild/linux-arm64': 0.16.17 + '@esbuild/linux-ia32': 0.16.17 + '@esbuild/linux-loong64': 0.16.17 + '@esbuild/linux-mips64el': 0.16.17 + '@esbuild/linux-ppc64': 0.16.17 + '@esbuild/linux-riscv64': 0.16.17 + '@esbuild/linux-s390x': 0.16.17 + '@esbuild/linux-x64': 0.16.17 + '@esbuild/netbsd-x64': 0.16.17 + '@esbuild/openbsd-x64': 0.16.17 + '@esbuild/sunos-x64': 0.16.17 + '@esbuild/win32-arm64': 0.16.17 + '@esbuild/win32-ia32': 0.16.17 + '@esbuild/win32-x64': 0.16.17 + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-vue@9.9.0(eslint@8.34.0): + dependencies: + eslint: 8.34.0 + eslint-utils: 3.0.0(eslint@8.34.0) + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.6.3 + vue-eslint-parser: 9.4.3(eslint@8.34.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-utils@3.0.0(eslint@8.34.0): + dependencies: + eslint: 8.34.0 + eslint-visitor-keys: 2.1.0 + + eslint-visitor-keys@2.1.0: {} + + eslint-visitor-keys@3.4.3: {} + + eslint@8.34.0: + dependencies: + '@eslint/eslintrc': 1.4.1 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.6 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-utils: 3.0.0(eslint@8.34.0) + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + grapheme-splitter: 1.0.4 + ignore: 5.3.2 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-sdsl: 4.4.2 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + regexpp: 3.2.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 3.4.3 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.3.1: {} + + follow-redirects@1.15.6: {} + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + grapheme-splitter@1.0.4: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + highlight.js@11.4.0: {} + + htmlparser2@9.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + immutable@4.3.7: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + isexe@2.0.0: {} + + js-sdsl@4.4.2: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.21: {} + + lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21): + dependencies: + '@types/lodash-es': 4.17.12 + lodash: 4.17.21 + lodash-es: 4.17.21 + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + magic-string@0.30.11: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + marked@4.3.0: {} + + memoize-one@6.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + ms@2.1.2: {} + + nanoid@3.3.7: {} + + natural-compare-lite@1.4.0: {} + + natural-compare@1.4.0: {} + + normalize-path@3.0.0: {} + + normalize-wheel-es@1.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-type@4.0.0: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pinia@2.1.6(typescript@4.9.5)(vue@3.3.4): + dependencies: + '@vue/devtools-api': 6.6.3 + vue: 3.3.4 + vue-demi: 0.14.10(vue@3.3.4) + optionalDependencies: + typescript: 4.9.5 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss@8.4.43: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + prelude-ls@1.2.1: {} + + prettier@2.8.4: {} + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regexpp@3.2.0: {} + + resolve-from@4.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup@3.29.4: + optionalDependencies: + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safer-buffer@2.1.2: {} + + sass@1.62.0: + dependencies: + chokidar: 3.6.0 + immutable: 4.3.7 + source-map-js: 1.2.0 + + semver@7.6.3: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + slash@3.0.0: {} + + source-map-js@1.2.0: {} + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + text-table@0.2.0: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tslib@1.14.1: {} + + tslib@2.3.0: {} + + tsutils@3.21.0(typescript@4.9.5): + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + typescript@4.9.5: {} + + undici@6.19.8: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + vite-plugin-qiankun@1.0.15(typescript@4.9.5)(vite@4.1.5(@types/node@20.5.9)(sass@1.62.0)): + dependencies: + cheerio: 1.0.0 + typescript: 4.9.5 + vite: 4.1.5(@types/node@20.5.9)(sass@1.62.0) + + vite@4.1.5(@types/node@20.5.9)(sass@1.62.0): + dependencies: + esbuild: 0.16.17 + postcss: 8.4.43 + resolve: 1.22.8 + rollup: 3.29.4 + optionalDependencies: + '@types/node': 20.5.9 + fsevents: 2.3.3 + sass: 1.62.0 + + vue-demi@0.13.11(vue@3.3.4): + dependencies: + vue: 3.3.4 + + vue-demi@0.14.10(vue@3.3.4): + dependencies: + vue: 3.3.4 + + vue-echarts@7.0.3(@vue/runtime-core@3.3.4)(echarts@5.4.3)(vue@3.3.4): + dependencies: + echarts: 5.4.3 + vue: 3.3.4 + vue-demi: 0.13.11(vue@3.3.4) + optionalDependencies: + '@vue/runtime-core': 3.3.4 + transitivePeerDependencies: + - '@vue/composition-api' + + vue-eslint-parser@9.4.3(eslint@8.34.0): + dependencies: + debug: 4.3.6 + eslint: 8.34.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + lodash: 4.17.21 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + + vue-i18n@9.14.0(vue@3.3.4): + dependencies: + '@intlify/core-base': 9.14.0 + '@intlify/shared': 9.14.0 + '@vue/devtools-api': 6.6.3 + vue: 3.3.4 + + vue-router@4.2.4(vue@3.3.4): + dependencies: + '@vue/devtools-api': 6.6.3 + vue: 3.3.4 + + vue@3.3.4: + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-sfc': 3.3.4 + '@vue/runtime-dom': 3.3.4 + '@vue/server-renderer': 3.3.4(vue@3.3.4) + '@vue/shared': 3.3.4 + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrappy@1.0.2: {} + + xml-name-validator@4.0.0: {} + + xss@1.0.14: + dependencies: + commander: 2.20.3 + cssfilter: 0.0.10 + + xterm-addon-attach@0.5.0(xterm@4.17.0): + dependencies: + xterm: 4.17.0 + + xterm-addon-fit@0.6.0(xterm@4.17.0): + dependencies: + xterm: 4.17.0 + + xterm@4.17.0: {} + + yocto-queue@0.1.0: {} + + zrender@5.4.4: + dependencies: + tslib: 2.3.0 diff --git a/public/404.html b/public/404.html new file mode 100755 index 0000000000000000000000000000000000000000..1b7822688907845ab031aee31379e4e0f4dbfb37 --- /dev/null +++ b/public/404.html @@ -0,0 +1,45 @@ + + + + + + + + openEuler Copilot System + + + + +
+ +

404 Page Not Found

+
+ + + \ No newline at end of file diff --git a/public/error.html b/public/error.html new file mode 100755 index 0000000000000000000000000000000000000000..b57f5e01706ae2539a0d87706bb124f0b3d1ae1f --- /dev/null +++ b/public/error.html @@ -0,0 +1,45 @@ + + + + + + + + openEuler Copilot System + + + + +
+ +

Error

+
+ + + \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100755 index 0000000000000000000000000000000000000000..6136282b79ccbc04a8160211b0640e86da415368 Binary files /dev/null and b/public/favicon.ico differ diff --git a/src/App.vue b/src/App.vue new file mode 100755 index 0000000000000000000000000000000000000000..592032d84e77869d0bd1a7675c5b2f5078a8a299 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,12 @@ + + + + + diff --git a/src/apis/index.ts b/src/apis/index.ts new file mode 100755 index 0000000000000000000000000000000000000000..19a573e034895d973d36b35b987cdff891879f3a --- /dev/null +++ b/src/apis/index.ts @@ -0,0 +1,18 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { accountApi, sessionApi, externalApi, apiKeyApi, knowledgeApi } from './paths'; + +export const api = { + ...accountApi, + ...sessionApi, + ...externalApi, + ...apiKeyApi, + ...knowledgeApi, +}; diff --git a/src/apis/paths/account.ts b/src/apis/paths/account.ts new file mode 100755 index 0000000000000000000000000000000000000000..671e214a59ed08803cbf8d2321642c8d1df22326 --- /dev/null +++ b/src/apis/paths/account.ts @@ -0,0 +1,139 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { get, post } from 'src/apis/server'; +import type { FcResponse } from 'src/apis/server'; + +/** + * 验证用户信息 + * @returns + */ +export const authorizeUser = (): Promise< + [ + any, + ( + | FcResponse<{ + user_sub: string; + username: string; + organization: string; + revision_number: string | null; + }> + | undefined + ) + ] +> => { + return get('/api/auth/user'); +}; + +/** + * 退出登录 + * @returns + */ +export const authorizeLogout = (): Promise<[any, FcResponse | undefined]> => { + return get('/api/auth/logout'); +}; + +/** + * 登录 + * @returns + */ +export const login = ( + code: string +): Promise< + [ + any, + ( + | FcResponse<{ + csrf_token: string; + }> + | undefined + ) + ] +> => { + return get('/api/auth/login', { code }); + +}; + +/** + * USER登录 + * @returns + */ +export const userLogin = ( + passwd: string, + account: string, +): Promise< + [ + any, + ( + | FcResponse<{ + csrf_token: string; + }> + | undefined + ) + ] +> => { + return get('/api/auth/login', { passwd, account }); +}; + +/** + * 刷新token + * @returns + */ +export const refreshToken = (): Promise< + [ + any, + ( + | FcResponse<{ + csrf_token: string; + }> + | undefined + ) + ] +> => { + return get('/api/auth/refresh_token'); +}; + +/** + * 更新签署服务协议版本 + * @param revisionNumber + * @returns + */ +export const updateRevision = ( + revisionNumber: number | string +): Promise< + [ + any, + ( + | FcResponse<{ + user_sub: string; + username: string; + organization: string; + revision_number: string | null; + }> + | undefined + ) + ] +> => { + return post('/api/auth/update_revision_number', { revision_num: revisionNumber }); +}; + + +function queryAuthUrl() { + return get('/api/auth/redirect'); +} + +export const accountApi = { + authorizeUser, + authorizeLogout, + login, + userLogin, + refreshToken, + updateRevision, + queryAuthUrl +}; diff --git a/src/apis/paths/apikey.ts b/src/apis/paths/apikey.ts new file mode 100755 index 0000000000000000000000000000000000000000..aa26beefd0f5b3fb139934ae60d070ddbe7a45a7 --- /dev/null +++ b/src/apis/paths/apikey.ts @@ -0,0 +1,56 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { get, post } from 'src/apis/server'; +import type { FcResponse } from 'src/apis/server'; + +/** + * 验证用户信息 + * @returns + */ +export const getApiKey = (): Promise< + [ + any, + ( + | FcResponse<{ + }> + | undefined + ) + ] +> => { + return get('/api/auth/key'); +}; + +/** + * USER登录 + * @returns + */ +export const changeApiKey = (params: { + action: string; + query?: string; +} + ): Promise< + [ + any, + ( + | FcResponse<{ + }> + | undefined + ) + ] + > => { + return post('/api/auth/key', params,params); + }; + + + +export const apiKeyApi = { + getApiKey, + changeApiKey, +}; diff --git a/src/apis/paths/conversation.ts b/src/apis/paths/conversation.ts new file mode 100755 index 0000000000000000000000000000000000000000..9616454ffa8369d4c6eda7cc171d6e69f750652c --- /dev/null +++ b/src/apis/paths/conversation.ts @@ -0,0 +1,185 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { get, put, post } from 'src/apis/server'; + +import type { FcResponse } from 'src/apis/server'; +const BASE_URL = '/api/conversation'; + +/** + * 停止生成 + * @returns + */ +export const stopGeneration = (): Promise< + [ + any, + ( + | FcResponse<{ + // conversation_id: string; + }> + | undefined + ) + ] +> => { + return post(`/api/stop`); +}; + +/** + * 获取历史session列表 + * @returns + */ +export const getSessionRecord = (): Promise< + [ + any, + ( + | FcResponse< + Array<{ + conversation_id: string; + title: string; + created_time: Date; + }> + > + | undefined + ) + ] +> => { + return get(BASE_URL); +}; + +/** + * 创建一个会话 + * @returns + */ +export const createSession = (): Promise< + [ + any, + ( + | FcResponse<{ + conversation_id: string; + }> + | undefined + ) + ] +> => { + return post(BASE_URL); +}; +/** + * 更新会话标题 + * @param params + * { + * conversation_id:(number)会话id + * title:(string)会话标题 + * } + * @returns + */ +export const updateSession = ( + params: { sessionId: string }, + data: { title: string } +): Promise< + [ + any, + ( + | FcResponse< + Array<{ + conversation_id: string; + }> + > + | undefined + ) + ] +> => { + return put(BASE_URL, data, { + conversation_id: params.sessionId, + }); +}; + +/** + * 删除会话 + * @param params + * @returns + */ +export const deleteSession = (params: { + conversation_list: string[]; +}): Promise<[any, FcResponse> | undefined]> => { + return post(`${BASE_URL}/delete`, params); +}; + +/** + * 获取会话历史对话记录 + * @param sessionId 会话id + */ +export const getHistoryConversation = ( + sessionId: string +): Promise< + [ + any, + ( + | FcResponse< + Array<{ + conversation_id: string; + record_id: string; + question: string; + answer: string; + created_time: string | Date; + is_like?: number | undefined; + group_id: string, + }> + > + | undefined + ) + ] +> => { + return get('/api/record', { conversation_id: sessionId }); +}; + +/** + * 评论对话 + * @param params + * @returns + */ +export const commentConversation = (params: { + qaRecordId: string; + isLike: number; + dislikeReason?: string; + reasonLink?: string; + reasonDescription?: string; +}): Promise<[any, FcResponse> | undefined]> => { + const { qaRecordId, isLike, dislikeReason, reasonLink, reasonDescription } = params; + return post(`/api/comment`, { + record_id: qaRecordId, + is_like: isLike, + dislike_reason: dislikeReason, + reason_link: reasonLink, + reason_description: reasonDescription, + }); +}; + +export const getRecognitionMode = (): Promise< + [ + any, + ( + | FcResponse< + Array<{ + id: string, + plugin_name: string + }>> + | undefined)]> => { + return get('/api/plugin'); +} + +export const sessionApi = { + createSession, + updateSession, + deleteSession, + getSessionRecord, + getHistoryConversation, + commentConversation, + getRecognitionMode, + stopGeneration: stopGeneration, +}; diff --git a/src/apis/paths/external.ts b/src/apis/paths/external.ts new file mode 100755 index 0000000000000000000000000000000000000000..cde11a662bcf4be05214679830d692624b55b237 --- /dev/null +++ b/src/apis/paths/external.ts @@ -0,0 +1,41 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { post } from 'src/apis/server'; +import type { FcResponse } from 'src/apis/server'; + +/** + * 反馈 + * @param params + * @returns + */ +export const feedback = (params: { + degree: number; + request_id: string; + feedback_tag?: string; + commont?: string; +}): Promise<[any, FcResponse | undefined]> => { + return post('/openlabs/qabot/satisfaction', params); +}; + +/** + * 反馈 + * @param params + * @returns + */ +export const report = (params: { + record_id: string; + reason: string; +}): Promise<[any, FcResponse | undefined]> => { + return post('/api/blacklist/complaint', params); +}; + +export const externalApi = { + feedback,report +}; diff --git a/src/apis/paths/index.ts b/src/apis/paths/index.ts new file mode 100755 index 0000000000000000000000000000000000000000..191ea5850e339b1aff339f92e0092d6a30b7c781 --- /dev/null +++ b/src/apis/paths/index.ts @@ -0,0 +1,15 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +export * from './account'; +export * from './conversation'; +export * from './external'; +export * from './apikey'; +export * from './knowledge'; + diff --git a/src/apis/paths/knowledge.ts b/src/apis/paths/knowledge.ts new file mode 100755 index 0000000000000000000000000000000000000000..646e5e59eb1aebbf6d8c38495957b8a3588509f2 --- /dev/null +++ b/src/apis/paths/knowledge.ts @@ -0,0 +1,54 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { get, post } from 'src/apis/server'; +import type { FcResponse } from 'src/apis/server'; + +/** + * 验证用户信息 + * @returns + */ +export const getKnowledgeList = (): Promise< + [ + any, + ( + | FcResponse<{ + }> + | undefined + ) + ] +> => { + return get('/api/knowledge/list'); +}; + +/** + * USER登录 + * @returns + */ +export const updateKnowledgeList = (params: { + kb_id: string; + }): Promise< + [ + any, + ( + | FcResponse<{ + }> + | undefined + ) + ] + > => { + return post('/api/knowledge/update', params); + }; + + + +export const knowledgeApi = { + getKnowledgeList, + updateKnowledgeList, +}; diff --git a/src/apis/server.ts b/src/apis/server.ts new file mode 100755 index 0000000000000000000000000000000000000000..6d404a6950cbaafdbc97143111df66acd5eedcc1 --- /dev/null +++ b/src/apis/server.ts @@ -0,0 +1,146 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import axios from "axios"; + +import { handleChangeRequestHeader, handleGeneralError, handleStatusError } from "./tools"; +import type { AxiosResponse, InternalAxiosRequestConfig } from "axios"; + +export interface FcResponse { + error: string; + errMessage: string; + result: T; +} + +interface MyResponseData { + code: number; + message: string; + result: T; +} + +export interface IAnyObj { + [index: string]: unknown; +} + +export type Fn = (data: FcResponse) => unknown; + +// 创建 axios 实例 +export const server = axios.create({ + // API 请求的默认前缀 + timeout: 60 * 1000, // 请求超时时间 +}); + +// request interceptor +server.interceptors.request.use( + ( + config: InternalAxiosRequestConfig + ): InternalAxiosRequestConfig | Promise> => { + return handleChangeRequestHeader(config); + }, + (error) => { + return Promise.reject(error); + } +); + +// response interceptor +server.interceptors.response.use( + (response: AxiosResponse): any => { + if (response.status !== 200) { + return Promise.reject(response.data); + } + // if (!handleGeneralError(response.data.code, response.data.label, response.data.err_msg)) { + // return false; + // } + return response; + }, + async (error) => { + return await handleStatusError(error); + } +); + +/** + * request with get + * @param url + * @param params + * @param clearFn + * @constructor + */ +export const get = async ( + url: string, + params: IAnyObj = {} +): Promise<[any, FcResponse | undefined]> => { + try { + const result = await server.get(url, { params }); + return [null, result.data as FcResponse]; + } catch (error) { + return [error, undefined]; + } +}; + +/** + * request with post + * @param url + * @param data + * @param params + * @constructor + */ +export const post = async ( + url: string, + data: IAnyObj = {}, + params: IAnyObj = {} +): Promise<[any, FcResponse | undefined]> => { + try { + const result = await server.post(url, data, { params }); + return [null, result.data as FcResponse]; + } catch (error) { + return [error, undefined]; + } +}; + +/** + * request with put + * @param url + * @param data + * @param params + * @constructor + */ +export const put = async ( + url: string, + data: IAnyObj = {}, + params: IAnyObj = {} +): Promise<[any, FcResponse | undefined]> => { + try { + const result = await server.put(url, data, { params }); + return [null, result.data as FcResponse]; + } catch (error) { + return [error, undefined]; + } +}; + +/** + * request with delete + * @param url + * @param params + * @constructor + */ +export const del = ( + url: string, + params: IAnyObj = {} +): Promise<[any, FcResponse | undefined]> => { + return new Promise((resolve) => { + server + .delete(url, { params }) + .then((result) => { + resolve([null, result.data as FcResponse]); + }) + .catch((err) => { + resolve([err, undefined]); + }); + }); +}; diff --git a/src/apis/tools.ts b/src/apis/tools.ts new file mode 100755 index 0000000000000000000000000000000000000000..02defe774ab7094e71d037295bc7f77a2f653a41 --- /dev/null +++ b/src/apis/tools.ts @@ -0,0 +1,181 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { ElNotification, ElMessageBox } from 'element-plus'; +import { CALLBACK_URL, LOGOUT_CALLBACK_URL } from 'src/views/dialogue/constants'; +import { useAccountStore } from 'src/store'; +import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper' + +import type { AxiosError, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; +import { storeToRefs } from 'pinia'; +import i18n from 'src/i18n' + +function getCookie(name: string) { + let matches = document.cookie.match(new RegExp( + "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)" + )); + return matches ? decodeURIComponent(matches[1]) : undefined; +} + +// 修改请求头 +export const handleChangeRequestHeader = ( + config: InternalAxiosRequestConfig +): InternalAxiosRequestConfig => { + config.headers['Content-Type'] = 'application/json; charset=UTF-8'; + const cookieValue = getCookie('_csrf_tk'); + if (cookieValue) { + config.headers['X-CSRF-Token'] = cookieValue; + } + return config; +}; + + +export const handleAuthorize = async (errStatus: number): Promise => { + const type = import.meta.env.VITE_USER_TYPE; + const store = useAccountStore() + const { userinfo } = storeToRefs(store); + userinfo.value.organization = type; + if ((errStatus === 401 || errStatus === 403)) { + if (qiankunWindow.__POWERED_BY_QIANKUN__) { + const url = await store.getAuthUrl() + if (url) { + const redirectUrl = qiankunWindow.__POWERED_BY_QIANKUN__ ? `${url}&redirect_index=${location.href}` : url + if (redirectUrl) + window.location.href = redirectUrl + } + } else { + ElMessageBox.confirm(i18n.global.t('Login.unauthorized'), i18n.global.t('history.confirmation_message1'), { + confirmButtonText: i18n.global.t('Login.login'), + showClose: false, + showCancelButton: false, + autofocus: false, + closeOnClickModal: false, + closeOnPressEscape: false, + }).then(async () => { + const url = await store.getAuthUrl() + if (url) { + const redirectUrl = qiankunWindow.__POWERED_BY_QIANKUN__ ? `${url}&redirect_index=${location.href}` : url + if (redirectUrl) + window.location.href = redirectUrl + } + } + ); + } + + } + if (errStatus === 460) { + window.open(LOGOUT_CALLBACK_URL, '_self'); + } +}; + + +export const handleNetworkError = (errStatus: number): void => { + let errMessage: string; + if (errStatus) { + switch (errStatus) { + case 400: + errMessage = '错误的请求'; + break; + case 403: + errMessage = '拒绝访问'; + break; + case 404: + errMessage = '请求错误,未找到该资源'; + break; + case 405: + errMessage = '请求方法未允许'; + break; + case 408: + errMessage = '请求超时'; + break; + case 500: + errMessage = '服务器端出错'; + break; + case 501: + errMessage = '网络未实现'; + break; + case 502: + errMessage = '网络错误'; + break; + case 503: + errMessage = '服务不可用'; + break; + case 504: + errMessage = '网络超时'; + break; + case 505: + errMessage = 'http版本不支持该请求'; + break; + default: + errMessage = `其他连接错误 --${errStatus}`; + } + } else { + errMessage = `无法连接到服务器!`; + } + + ElNotification.error({ + title: '错误', + message: errMessage, + }); +}; + +export const handleGeneralError = ( + errno: number, + errorLabel: string = 'Fail', + errMessage: string = 'request error' +): boolean => { + if (Number(errno) !== 200 && Number(errno) !== 401 && Number(errno) !== 403 && Number(errno) !== 302 && Number(errno) !== 2001) { + ElNotification.error({ + title: errorLabel, + message: errMessage, + }); + return false; + } + return true; +}; + + + + +/** + * 处理状态码错误 + */ +export const handleStatusError = async ( + error: AxiosError +): Promise[] | undefined> => { + if (!error.response) { + // 如果没有响应,可能是网络问题或其他非HTTP错误,直接返回错误 + return Promise.reject(error); + } + + const { status } = error.response; + if ([401, 403, 460].includes(status)) { + if (status === 401) { + handleAuthorize(status); + return; + } + const originalRequest = error.config; + if (originalRequest.url === '/api/auth/refresh_token') { + // 长token过期,需要重新登录 + handleAuthorize(status); + return Promise.reject(error.response); + } + if (originalRequest.url === '/api/auth/user') { + handleAuthorize(status); + return; + } + //引入新的cookie后,会根据用户的请求重置token有效期,先删除重发逻辑,后期修改 + // const suc = await refreshToken(originalRequest); + // if(!suc){ + // return Promise.reject(error.response); + // } + // return server(originalRequest); + } + return Promise.reject(error.response); +}; \ No newline at end of file diff --git a/src/assets/base.css b/src/assets/base.css new file mode 100755 index 0000000000000000000000000000000000000000..8a1816f5ffa1d6bb08dd46a0a85ff65e8e1617ce --- /dev/null +++ b/src/assets/base.css @@ -0,0 +1,38 @@ +@font-face { + font-family: 'HarmonyOS_Sans_SC_Medium'; + src: url('./fonts/HarmonyOS_Sans_SC_Medium.ttf'); + font-weight: normal; + font-style: normal; +} +* { + font-family: HarmonyOS_Sans_SC_Medium, 'Helvetica Neue', Helvetica, 'PingFang SC', + 'Hiragino Sans GB', 'Microsoft YaHei', '微软雅黑', Arial, sans-serif; +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + padding: 0; +} +li { + list-style-type: none; + cursor: pointer; +} +textarea { + resize: none; +} +svg:focus { + outline: none; +} + +body { + min-height: 100vh; + transition: color 0.5s, background-color 0.5s; + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, + Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + background-color: #f5f5f6; +} diff --git a/src/assets/color.js b/src/assets/color.js new file mode 100755 index 0000000000000000000000000000000000000000..5a19ae43380f1936b2efe643f5859b3d6af21110 --- /dev/null +++ b/src/assets/color.js @@ -0,0 +1,15 @@ +const color = [ + "#0062DC", + "#2DB47C", + "#EC4F83", + "#3DB6FC", + "#6D47F5", + "#3DCFD4", + "#BD45E8", + "#81BA06", + "#FF5432", + "#9EA8B9", + ]; + + export default color; + \ No newline at end of file diff --git a/src/assets/fonts/HarmonyOS_Sans_SC_Medium.ttf b/src/assets/fonts/HarmonyOS_Sans_SC_Medium.ttf new file mode 100755 index 0000000000000000000000000000000000000000..6d8eab7f749328780ec0843ac557cfbf36e5e1e6 Binary files /dev/null and b/src/assets/fonts/HarmonyOS_Sans_SC_Medium.ttf differ diff --git a/src/assets/images/application_cases.png b/src/assets/images/application_cases.png new file mode 100755 index 0000000000000000000000000000000000000000..1475af31c6c20c0b9e96b8969132822e16907953 Binary files /dev/null and b/src/assets/images/application_cases.png differ diff --git a/src/assets/images/cancel.svg b/src/assets/images/cancel.svg new file mode 100755 index 0000000000000000000000000000000000000000..89f0b0487b15d6680e10a2987fbc3e839cf82c6a --- /dev/null +++ b/src/assets/images/cancel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/command_generation.png b/src/assets/images/command_generation.png new file mode 100755 index 0000000000000000000000000000000000000000..d4a6698fcedf0827eaa78ac255ae5b0f9f3dc704 Binary files /dev/null and b/src/assets/images/command_generation.png differ diff --git a/src/assets/images/confirm.svg b/src/assets/images/confirm.svg new file mode 100755 index 0000000000000000000000000000000000000000..7fe8ed84cdf609336d38dfff1f334732e4584240 --- /dev/null +++ b/src/assets/images/confirm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/corpus.svg b/src/assets/images/corpus.svg new file mode 100755 index 0000000000000000000000000000000000000000..d69a8716da4bb9e78b5e6f1fecc871a104958d81 --- /dev/null +++ b/src/assets/images/corpus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/dark_application_case.png b/src/assets/images/dark_application_case.png new file mode 100755 index 0000000000000000000000000000000000000000..63492165db2f13ac118247e603728582bfecc5ab Binary files /dev/null and b/src/assets/images/dark_application_case.png differ diff --git a/src/assets/images/dark_application_case.svg b/src/assets/images/dark_application_case.svg new file mode 100755 index 0000000000000000000000000000000000000000..c24652e130dcb1246648db39bca2b8570c2d42ae --- /dev/null +++ b/src/assets/images/dark_application_case.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/dark_background.png b/src/assets/images/dark_background.png new file mode 100755 index 0000000000000000000000000000000000000000..7f69af52de289f60769523385b1528fc75e69ee5 Binary files /dev/null and b/src/assets/images/dark_background.png differ diff --git a/src/assets/images/dark_command_generation.png b/src/assets/images/dark_command_generation.png new file mode 100755 index 0000000000000000000000000000000000000000..8a3a9bd9f8a6d510d102a033b8f53634a4a824af Binary files /dev/null and b/src/assets/images/dark_command_generation.png differ diff --git a/src/assets/images/dark_command_generation.svg b/src/assets/images/dark_command_generation.svg new file mode 100755 index 0000000000000000000000000000000000000000..44ac9cb4728f3bd0286369b11e14291a2f7bfe89 --- /dev/null +++ b/src/assets/images/dark_command_generation.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/dark_expand_knowledge.png b/src/assets/images/dark_expand_knowledge.png new file mode 100755 index 0000000000000000000000000000000000000000..530907263a776d299429d93d06a4947668326965 Binary files /dev/null and b/src/assets/images/dark_expand_knowledge.png differ diff --git a/src/assets/images/dark_expand_knowledge.svg b/src/assets/images/dark_expand_knowledge.svg new file mode 100755 index 0000000000000000000000000000000000000000..f7204d99677f649796e0eff5a09f9004a1233cac --- /dev/null +++ b/src/assets/images/dark_expand_knowledge.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/dark_expertise.png b/src/assets/images/dark_expertise.png new file mode 100755 index 0000000000000000000000000000000000000000..4e22af5478e83889cfbcd839d1e3d829bff644d9 Binary files /dev/null and b/src/assets/images/dark_expertise.png differ diff --git a/src/assets/images/dark_expertise.svg b/src/assets/images/dark_expertise.svg new file mode 100755 index 0000000000000000000000000000000000000000..e86074fdc157d332bfd3aec7d331c6ddd442efb5 --- /dev/null +++ b/src/assets/images/dark_expertise.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/dark_general_knowledge.png b/src/assets/images/dark_general_knowledge.png new file mode 100755 index 0000000000000000000000000000000000000000..81e4827b3f29dfc282247c8d8e1aeece7d6bdd07 Binary files /dev/null and b/src/assets/images/dark_general_knowledge.png differ diff --git a/src/assets/images/dark_general_knowledge.svg b/src/assets/images/dark_general_knowledge.svg new file mode 100755 index 0000000000000000000000000000000000000000..8530a956b7b4e3d6e52ca2d4d6ff5cd147248b4e --- /dev/null +++ b/src/assets/images/dark_general_knowledge.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/dark_send.png b/src/assets/images/dark_send.png new file mode 100755 index 0000000000000000000000000000000000000000..1555c7b40210a99dcd49af2bc83c049a9efefcb8 Binary files /dev/null and b/src/assets/images/dark_send.png differ diff --git a/src/assets/images/dark_shell.png b/src/assets/images/dark_shell.png new file mode 100755 index 0000000000000000000000000000000000000000..d9b94d8980c7ba8c884398143589bf4116286bd6 Binary files /dev/null and b/src/assets/images/dark_shell.png differ diff --git a/src/assets/images/dark_sider-active.png b/src/assets/images/dark_sider-active.png new file mode 100755 index 0000000000000000000000000000000000000000..64ef9312b39a1e3ea2aba289d0c6b3fce225cdd9 Binary files /dev/null and b/src/assets/images/dark_sider-active.png differ diff --git a/src/assets/images/dark_sider-hover.png b/src/assets/images/dark_sider-hover.png new file mode 100755 index 0000000000000000000000000000000000000000..7f3a468d523d611b155d35885f906b25d5021789 Binary files /dev/null and b/src/assets/images/dark_sider-hover.png differ diff --git a/src/assets/images/dark_sider.png b/src/assets/images/dark_sider.png new file mode 100755 index 0000000000000000000000000000000000000000..bf498d4b7d53361e44b6799d12337f073c6f0128 Binary files /dev/null and b/src/assets/images/dark_sider.png differ diff --git a/src/assets/images/dark_user.png b/src/assets/images/dark_user.png new file mode 100755 index 0000000000000000000000000000000000000000..8d72185116ade40e9c0605b4a460f3326c548069 Binary files /dev/null and b/src/assets/images/dark_user.png differ diff --git a/src/assets/images/edit.svg b/src/assets/images/edit.svg new file mode 100755 index 0000000000000000000000000000000000000000..1bed46a421af200542a22cb89099ee6a77562417 --- /dev/null +++ b/src/assets/images/edit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/images/euler_copilot.png b/src/assets/images/euler_copilot.png new file mode 100755 index 0000000000000000000000000000000000000000..8d905d7cc85a7183aad65cd13c54006cff832c39 Binary files /dev/null and b/src/assets/images/euler_copilot.png differ diff --git a/src/assets/images/expanded_knowledge.png b/src/assets/images/expanded_knowledge.png new file mode 100755 index 0000000000000000000000000000000000000000..2d808c88351ad677b147454e95993f67da120dd1 Binary files /dev/null and b/src/assets/images/expanded_knowledge.png differ diff --git a/src/assets/images/expertise.png b/src/assets/images/expertise.png new file mode 100755 index 0000000000000000000000000000000000000000..ae238cd57d4f15e596c8f8ff055d8736bd6cf061 Binary files /dev/null and b/src/assets/images/expertise.png differ diff --git a/src/assets/images/general_knowledge.png b/src/assets/images/general_knowledge.png new file mode 100755 index 0000000000000000000000000000000000000000..c96ca2f7dd6384cb7c59cc411ad7c69bd095a666 Binary files /dev/null and b/src/assets/images/general_knowledge.png differ diff --git a/src/assets/images/light_application_case.png b/src/assets/images/light_application_case.png new file mode 100755 index 0000000000000000000000000000000000000000..74d613c30886b732993777db7c86d2c91b1c7ca6 Binary files /dev/null and b/src/assets/images/light_application_case.png differ diff --git a/src/assets/images/light_application_case.svg b/src/assets/images/light_application_case.svg new file mode 100755 index 0000000000000000000000000000000000000000..c528728c48295b482e04f8bdf38821434667157b --- /dev/null +++ b/src/assets/images/light_application_case.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/light_background.png b/src/assets/images/light_background.png new file mode 100755 index 0000000000000000000000000000000000000000..4a9604232d850f1a6fdebe18c2cf589171e679ef Binary files /dev/null and b/src/assets/images/light_background.png differ diff --git a/src/assets/images/light_command_generation.png b/src/assets/images/light_command_generation.png new file mode 100755 index 0000000000000000000000000000000000000000..c68478a296111238e0c8942139315852d268785c Binary files /dev/null and b/src/assets/images/light_command_generation.png differ diff --git a/src/assets/images/light_command_generation.svg b/src/assets/images/light_command_generation.svg new file mode 100755 index 0000000000000000000000000000000000000000..6ff305e02f19940fca4b7cc8a3e28b51ffde686b --- /dev/null +++ b/src/assets/images/light_command_generation.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/light_expand_knowledge.png b/src/assets/images/light_expand_knowledge.png new file mode 100755 index 0000000000000000000000000000000000000000..4bcb77abf67545f6d7b1994143b7408ec36188ee Binary files /dev/null and b/src/assets/images/light_expand_knowledge.png differ diff --git a/src/assets/images/light_expand_knowledge.svg b/src/assets/images/light_expand_knowledge.svg new file mode 100755 index 0000000000000000000000000000000000000000..f8943637eb559c99d9bbdfdf5c59b11500c2a12b --- /dev/null +++ b/src/assets/images/light_expand_knowledge.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/light_expertise.png b/src/assets/images/light_expertise.png new file mode 100755 index 0000000000000000000000000000000000000000..4e22af5478e83889cfbcd839d1e3d829bff644d9 Binary files /dev/null and b/src/assets/images/light_expertise.png differ diff --git a/src/assets/images/light_expertise.svg b/src/assets/images/light_expertise.svg new file mode 100755 index 0000000000000000000000000000000000000000..5759373d0c724fe8b3e7c77a37f732a36fc11c63 --- /dev/null +++ b/src/assets/images/light_expertise.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/light_general_knowledge.png b/src/assets/images/light_general_knowledge.png new file mode 100755 index 0000000000000000000000000000000000000000..a3bcc0ecde2a08d1b0380c7f1c0d5d90b745e2f1 Binary files /dev/null and b/src/assets/images/light_general_knowledge.png differ diff --git a/src/assets/images/light_general_knowledge.svg b/src/assets/images/light_general_knowledge.svg new file mode 100755 index 0000000000000000000000000000000000000000..6e0aae8ec7288330612b8439f2fc9c858565405b --- /dev/null +++ b/src/assets/images/light_general_knowledge.svg @@ -0,0 +1,29 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/light_send.png b/src/assets/images/light_send.png new file mode 100755 index 0000000000000000000000000000000000000000..c859a286bababe80b778382a5a925f69580bb697 Binary files /dev/null and b/src/assets/images/light_send.png differ diff --git a/src/assets/images/light_shell.png b/src/assets/images/light_shell.png new file mode 100755 index 0000000000000000000000000000000000000000..90d036a5be7d4249d71a975bd10f7d9380167eb1 Binary files /dev/null and b/src/assets/images/light_shell.png differ diff --git a/src/assets/images/light_sider-active.png b/src/assets/images/light_sider-active.png new file mode 100755 index 0000000000000000000000000000000000000000..2f4ae479b60854b779ac02fab34672723ffc98d5 Binary files /dev/null and b/src/assets/images/light_sider-active.png differ diff --git a/src/assets/images/light_sider-hover.png b/src/assets/images/light_sider-hover.png new file mode 100755 index 0000000000000000000000000000000000000000..7084444a11950199db449bdbbbba9c2ea1ef06cd Binary files /dev/null and b/src/assets/images/light_sider-hover.png differ diff --git a/src/assets/images/light_sider.png b/src/assets/images/light_sider.png new file mode 100755 index 0000000000000000000000000000000000000000..8748d6981b9b91879ed19d0585bc3fe7fd4c1c2e Binary files /dev/null and b/src/assets/images/light_sider.png differ diff --git a/src/assets/images/light_user.png b/src/assets/images/light_user.png new file mode 100755 index 0000000000000000000000000000000000000000..4593adfc4cb6d54e156de64035f94ca3c2ae0962 Binary files /dev/null and b/src/assets/images/light_user.png differ diff --git a/src/assets/images/loading.png b/src/assets/images/loading.png new file mode 100755 index 0000000000000000000000000000000000000000..e9f712593db317bbaeee82e07dcdd565166ff0cc Binary files /dev/null and b/src/assets/images/loading.png differ diff --git a/src/assets/images/logoText.png b/src/assets/images/logoText.png new file mode 100755 index 0000000000000000000000000000000000000000..6f12e302f59509e15dc12460a080253d5011ac6c Binary files /dev/null and b/src/assets/images/logoText.png differ diff --git a/src/assets/images/oepkg.png b/src/assets/images/oepkg.png new file mode 100755 index 0000000000000000000000000000000000000000..b3c924accce7efa1c7af847f7cd6adaea484a716 Binary files /dev/null and b/src/assets/images/oepkg.png differ diff --git a/src/assets/images/pkgship.png b/src/assets/images/pkgship.png new file mode 100755 index 0000000000000000000000000000000000000000..5a0cdbb1f7f2fbaf44bc5c6ad5b6623a21c35f27 Binary files /dev/null and b/src/assets/images/pkgship.png differ diff --git a/src/assets/images/robot.png b/src/assets/images/robot.png new file mode 100755 index 0000000000000000000000000000000000000000..30070d7d9e6420ec9bc6d1f6042fe560d3a3666c Binary files /dev/null and b/src/assets/images/robot.png differ diff --git a/src/assets/images/send_disable.png b/src/assets/images/send_disable.png new file mode 100755 index 0000000000000000000000000000000000000000..913e57b6710c4d717f8a18761ef03455531d9d8b Binary files /dev/null and b/src/assets/images/send_disable.png differ diff --git a/src/assets/styles/codePreview.scss b/src/assets/styles/codePreview.scss new file mode 100755 index 0000000000000000000000000000000000000000..7783c926014df6f2ea6c2095522f09685e598ff1 --- /dev/null +++ b/src/assets/styles/codePreview.scss @@ -0,0 +1,124 @@ +#markdown-preview { + + .hljs{ + color: var(--o-text-color-secondary); + } + //markdown text size + p{ + font-size: 16px; + font-weight: 400; + } + + table { + border-collapse: collapse; + margin: 16px 0; + } + + /* 表头样式 */ + thead { + background-color: var(--o-bg-color-light); + color: var(--o-text-color-secondary); + } + thead th { + text-align: left; + padding: 7px; + white-space: nowrap; + } + + /* 表格主体样式 */ + tbody tr { + transition: background-color 0.3s ease; + } + tbody tr:nth-child(even) { + background-color: var(--o-bg-color-light); + } + tbody td { + padding: 3px 24px 3px 7px; + text-align: left; + vertical-align: middle; + color: var(--o-text-color-primarys); + } + + @media screen and (max-width: 600px) { + table, + thead, + tbody, + th, + td, + tr { + display: block; + } + + thead tr { + position: absolute; + top: -9999px; + left: -9999px; + } + + tr { + margin-bottom: 1rem; + } + + td { + border: none; + position: relative; + padding-left: 50%; + } + + td:before { + content: attr(data-label); + position: absolute; + left: 10px; + top: 0; + width: 45%; + font-weight: bold; + white-space: nowrap; + } + } + pre { + overflow-wrap: break-word; + word-break: break-all; + white-space: pre-wrap; /* 保持缩进同时允许换行 */ + margin: 8px 0px; + .code-toolbar { + background-color: var(--o-bash-bg); + color: var(--o-text-color-primarys); + display: flex; + justify-content: space-between; + align-items: center; + border-radius: 8px 8px 0 0; + padding: 8px 12px 0 12px; + font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, + Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; + .pre-copy { + cursor: pointer; + svg { + vertical-align: middle; + } + &:hover { + color: var(--o-text-color-secondary); + } + } + } + code { + background-color: var(--o-bash-bg); + border-radius: 0 0 8px 8px; + } + } + + a { + color: #6395fd; + &:hover { + color: #7aa5ff; + } + } + + ol { + margin-left: 16px; + li{ + list-style-type: decimal; + cursor: default; + margin-left: 12px; + } + } +} diff --git a/src/assets/styles/element/index.scss b/src/assets/styles/element/index.scss new file mode 100755 index 0000000000000000000000000000000000000000..c6b7bd8c3cc9d3d56409e56d4ab3e91815012c96 --- /dev/null +++ b/src/assets/styles/element/index.scss @@ -0,0 +1,77 @@ +:root { + --el-color-primary: #0077ff; +} + + +.euler-copilot-message-box { + background-color: #fefefe; + border-radius: 4px; + .el-message-box__header { + font-weight: bold; + box-shadow: inset 0 -1px 0 0#dfe5ef; + } +} + +.el-message-box { + width: 432px !important; + height: 184px !important; +} + +.el-button:not(.is-disabled){ + // background-color: white !important; + color: var(--o-button-color) !important; + border-color: var(--o-button-border-color) !important; +} + +.el-button:not(.is-disabled):focus{ + // background-color: white !important; + color:var(--o-button-color) !important; + border-color: var(--o-button-border-color) !important; +} + +.el-button:not(.is-disabled):active{ + // background-color: white !important; + color: #6395FD !important; + border-color: #6395FD !important; +} + +.el-button:not(.is-disabled):hover{ + // background-color: white !important; + color: #7AA5FF !important; + border-color: #7AA5FF !important; +} + + + + +.el-button--primary:not(.is-disabled){ + background-color: #6395FD !important; + color: white !important; + border-color: #6395FD !important; +} + +.el-button--primary:not(.is-disabled):focus{ + background-color: #6395FD !important; + color: white !important; + border-color: #6395FD !important; +} + +.el-button--primary:not(.is-disabled):active{ + background-color: #6395FD !important; + color: white !important; + border-color: #6395FD !important; +} + +.el-button--primary:not(.is-disabled):hover{ + background-color: #7AA5FF !important; + color: white !important; + border-color: #7AA5FF !important; +} + +.el-message{ + --o-message-border-radius:8px !important; +} + +.exit-button{ + margin-left: 0px !important; +} \ No newline at end of file diff --git a/src/assets/styles/main.scss b/src/assets/styles/main.scss new file mode 100755 index 0000000000000000000000000000000000000000..e303235f640e44854e38bc80b1ccf81862473ca9 --- /dev/null +++ b/src/assets/styles/main.scss @@ -0,0 +1,3 @@ +@import './codePreview.scss'; +@import './message.scss'; +@import './theme.scss' \ No newline at end of file diff --git a/src/assets/styles/message.scss b/src/assets/styles/message.scss new file mode 100755 index 0000000000000000000000000000000000000000..9874697ee866f69a74117cdad9bc8c8a5d692602 --- /dev/null +++ b/src/assets/styles/message.scss @@ -0,0 +1,40 @@ + +.el-message{ + width: 30%; + border-radius: 5px; + } + + .el-message--success{ + background-color: #C2E7C7; + color: #000; + border-color: #24AB36; + border-radius: 10px; + .el-message__content{ + color: #000; + font-size: 12px; + + } + } + + .el-message--warning{ + background-color: #F9ECB8; + border-color: #EBAF00; + img{ + width: 16px; + height: 16px; + } + .el-message__content{ + color: #000; + font-size: 12px; + } + } + + .el-message--error{ + background-color: #F7C1C1; + color: #000; + border-color: #E42121; + .el-message__content{ + color: #000; + font-size: 12px; + } + } \ No newline at end of file diff --git a/src/assets/styles/theme.scss b/src/assets/styles/theme.scss new file mode 100755 index 0000000000000000000000000000000000000000..451e8d1d706d7bb939c7b454ea2af53f30ec0e44 --- /dev/null +++ b/src/assets/styles/theme.scss @@ -0,0 +1,27 @@ +body[theme='dark'] { + --o-bg-image: url('../../assets/images/dark_background.png'); + --o-shell-image: url('../../assets/images/dark_shell.png'); + --o-sider: url('../../assets/images/dark_sider.png'); + --o-sider-hover: url('../../assets/images/dark_sider-hover.png'); + --o-button-color: #576372; + --o-button-border-color: #576372; + --o-button-disable-color: #626d7c; + --o-button-disable-background: #203052; + --o-button-disable-border: #626d7c; + --o-time-text: #3e4551; + --o-bash-bg: #2a2f37; +} + +body[theme='light'] { + --o-bg-image: url('../../assets/images/light_background.png'); + --o-shell-image: url('../../assets/images/light_shell.png'); + --o-sider: url('../../assets/images/light_sider.png'); + --o-sider-hover: url('../../assets/images/light_sider-hover.png'); + --o-button-color: #c3cedf; + --o-button-border-color: #d3dce9; + --o-button-disable-color: #bfc7d7; + --o-button-disable-background: #ebedf3; + --o-button-disable-border: #ebedf3; + --o-time-text: #dfe5ef; + --o-bash-bg: #f4f6fa; +} diff --git a/src/assets/svgs/against_active.svg b/src/assets/svgs/against_active.svg new file mode 100755 index 0000000000000000000000000000000000000000..585e786f83a40ae67fa6e57dd4be488bc12f45dd --- /dev/null +++ b/src/assets/svgs/against_active.svg @@ -0,0 +1,15 @@ + + + Created with Pixso. + + + + + + + + + + + + diff --git a/src/assets/svgs/alarm.svg b/src/assets/svgs/alarm.svg new file mode 100755 index 0000000000000000000000000000000000000000..df7271a06290438787905774d58bed1b27551e5b --- /dev/null +++ b/src/assets/svgs/alarm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/arror_left.svg b/src/assets/svgs/arror_left.svg new file mode 100755 index 0000000000000000000000000000000000000000..9202dda4c39459b5d0d87f2e70a766e93fc7982c --- /dev/null +++ b/src/assets/svgs/arror_left.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/arror_right.svg b/src/assets/svgs/arror_right.svg new file mode 100755 index 0000000000000000000000000000000000000000..11916c276872604342db48602d27de35c3a49aa0 --- /dev/null +++ b/src/assets/svgs/arror_right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/blank.svg b/src/assets/svgs/blank.svg new file mode 100755 index 0000000000000000000000000000000000000000..2f326bc59b4d74e0d2b404e75a331afeb8f7c930 --- /dev/null +++ b/src/assets/svgs/blank.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/copy.svg b/src/assets/svgs/copy.svg new file mode 100755 index 0000000000000000000000000000000000000000..db2c9c0e7f61200e49596873d3cf20d11baa37e6 --- /dev/null +++ b/src/assets/svgs/copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/corpus.svg b/src/assets/svgs/corpus.svg new file mode 100755 index 0000000000000000000000000000000000000000..d69a8716da4bb9e78b5e6f1fecc871a104958d81 --- /dev/null +++ b/src/assets/svgs/corpus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/create.svg b/src/assets/svgs/create.svg new file mode 100755 index 0000000000000000000000000000000000000000..a9a9df7b94f3fc19890c8030515b38e648fb0f7c --- /dev/null +++ b/src/assets/svgs/create.svg @@ -0,0 +1,31 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/svgs/dark_against.svg b/src/assets/svgs/dark_against.svg new file mode 100755 index 0000000000000000000000000000000000000000..26f7835ef840d68d5f40c8334b57558189a0f47b --- /dev/null +++ b/src/assets/svgs/dark_against.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/assets/svgs/dark_change.svg b/src/assets/svgs/dark_change.svg new file mode 100755 index 0000000000000000000000000000000000000000..77baea77bfe822e7e4a9eb6d3530e8c9ffb805f0 --- /dev/null +++ b/src/assets/svgs/dark_change.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/assets/svgs/dark_copy.svg b/src/assets/svgs/dark_copy.svg new file mode 100755 index 0000000000000000000000000000000000000000..d125b6a9e9a0a0a545129ff9ad365e7fab8ff6a1 --- /dev/null +++ b/src/assets/svgs/dark_copy.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/dark_delete.svg b/src/assets/svgs/dark_delete.svg new file mode 100755 index 0000000000000000000000000000000000000000..590235f38b729b9cfd0e0862a8449f4ecaf8b9fb --- /dev/null +++ b/src/assets/svgs/dark_delete.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/src/assets/svgs/dark_editor.svg b/src/assets/svgs/dark_editor.svg new file mode 100755 index 0000000000000000000000000000000000000000..967e23886672504b9b17217673f1cd8ff09b66df --- /dev/null +++ b/src/assets/svgs/dark_editor.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/assets/svgs/dark_null.svg b/src/assets/svgs/dark_null.svg new file mode 100755 index 0000000000000000000000000000000000000000..a406ee17ba71102ae1bf7dde17abae34cd2feb78 --- /dev/null +++ b/src/assets/svgs/dark_null.svg @@ -0,0 +1,90 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/svgs/dark_regenerate.svg b/src/assets/svgs/dark_regenerate.svg new file mode 100755 index 0000000000000000000000000000000000000000..d048b8d377bc0b237a527102d590bb809e2f70a5 --- /dev/null +++ b/src/assets/svgs/dark_regenerate.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/dark_report.svg b/src/assets/svgs/dark_report.svg new file mode 100755 index 0000000000000000000000000000000000000000..6dbb08b0a035fb799e0e9b424e3b7bfa5c038358 --- /dev/null +++ b/src/assets/svgs/dark_report.svg @@ -0,0 +1,17 @@ + + + Created with Pixso. + + + + + + + + + + + + + + diff --git a/src/assets/svgs/dark_stop_answer.svg b/src/assets/svgs/dark_stop_answer.svg new file mode 100755 index 0000000000000000000000000000000000000000..e56cadccd698903b2f50f8b15dff356eac692a9b --- /dev/null +++ b/src/assets/svgs/dark_stop_answer.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/src/assets/svgs/dark_support.svg b/src/assets/svgs/dark_support.svg new file mode 100755 index 0000000000000000000000000000000000000000..c4a96c4bc7357e598cef2f5abce811f29cbabefe --- /dev/null +++ b/src/assets/svgs/dark_support.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/delete.svg b/src/assets/svgs/delete.svg new file mode 100755 index 0000000000000000000000000000000000000000..17851757f9173591fbb32ad05235f0a3b47b2932 --- /dev/null +++ b/src/assets/svgs/delete.svg @@ -0,0 +1,10 @@ + + + + + \ No newline at end of file diff --git a/src/assets/svgs/delete_hover.svg b/src/assets/svgs/delete_hover.svg new file mode 100755 index 0000000000000000000000000000000000000000..9545770279dc679af1bace6e0fd3c2653acb2eab --- /dev/null +++ b/src/assets/svgs/delete_hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/editor.svg b/src/assets/svgs/editor.svg new file mode 100755 index 0000000000000000000000000000000000000000..1bed46a421af200542a22cb89099ee6a77562417 --- /dev/null +++ b/src/assets/svgs/editor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/editor_hover.svg b/src/assets/svgs/editor_hover.svg new file mode 100755 index 0000000000000000000000000000000000000000..93b37e908bae5dab30878078958765f3f871205d --- /dev/null +++ b/src/assets/svgs/editor_hover.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/empty.svg b/src/assets/svgs/empty.svg new file mode 100755 index 0000000000000000000000000000000000000000..c39894c9be7581fb4daf16bc9275bd66a4f67db2 --- /dev/null +++ b/src/assets/svgs/empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/error.svg b/src/assets/svgs/error.svg new file mode 100755 index 0000000000000000000000000000000000000000..eff026d9a371ecd397542f213880a651cb1559cf --- /dev/null +++ b/src/assets/svgs/error.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/src/assets/svgs/euler_copilot_logo.svg b/src/assets/svgs/euler_copilot_logo.svg new file mode 100755 index 0000000000000000000000000000000000000000..2ac4fced1382e233d40e6f566e68bc4570c96dd4 --- /dev/null +++ b/src/assets/svgs/euler_copilot_logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/hiss.svg b/src/assets/svgs/hiss.svg new file mode 100755 index 0000000000000000000000000000000000000000..9d5cdd7a645832a44a044da2a8a3e6a9cec038d5 --- /dev/null +++ b/src/assets/svgs/hiss.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/light_against.svg b/src/assets/svgs/light_against.svg new file mode 100755 index 0000000000000000000000000000000000000000..1f257ac8e47d215b85022c8d96d6c20cec24c050 --- /dev/null +++ b/src/assets/svgs/light_against.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/assets/svgs/light_change.svg b/src/assets/svgs/light_change.svg new file mode 100755 index 0000000000000000000000000000000000000000..d09f2050fa7948ec5d793b8dc0c784f743a3f1ff --- /dev/null +++ b/src/assets/svgs/light_change.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/assets/svgs/light_copy.svg b/src/assets/svgs/light_copy.svg new file mode 100755 index 0000000000000000000000000000000000000000..41a377ccc9d43f20f0f2298e47766cf16081cac9 --- /dev/null +++ b/src/assets/svgs/light_copy.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/light_delete.svg b/src/assets/svgs/light_delete.svg new file mode 100755 index 0000000000000000000000000000000000000000..cb120ed25c0efc717e8105a1ab0fd0794fb538f9 --- /dev/null +++ b/src/assets/svgs/light_delete.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/src/assets/svgs/light_editor.svg b/src/assets/svgs/light_editor.svg new file mode 100755 index 0000000000000000000000000000000000000000..5360033a2fbdeb90edaef70546e3ea7d20598711 --- /dev/null +++ b/src/assets/svgs/light_editor.svg @@ -0,0 +1,14 @@ + + + Created with Pixso. + + + + + + + + + + + diff --git a/src/assets/svgs/light_null.svg b/src/assets/svgs/light_null.svg new file mode 100755 index 0000000000000000000000000000000000000000..df04da463d36bb63b871562bbf7b9737e61a8d7e --- /dev/null +++ b/src/assets/svgs/light_null.svg @@ -0,0 +1,68 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/svgs/light_regenerate.svg b/src/assets/svgs/light_regenerate.svg new file mode 100755 index 0000000000000000000000000000000000000000..ef11c3d71ec2393b73238886e6b336df3f56f0aa --- /dev/null +++ b/src/assets/svgs/light_regenerate.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/light_report.svg b/src/assets/svgs/light_report.svg new file mode 100755 index 0000000000000000000000000000000000000000..3487eb488c2f812652db5e3933f9cd874843e104 --- /dev/null +++ b/src/assets/svgs/light_report.svg @@ -0,0 +1,17 @@ + + + Created with Pixso. + + + + + + + + + + + + + + diff --git a/src/assets/svgs/light_stop_answer.svg b/src/assets/svgs/light_stop_answer.svg new file mode 100755 index 0000000000000000000000000000000000000000..fee36bff97e1faf6cd138d02acc21436baf9d27b --- /dev/null +++ b/src/assets/svgs/light_stop_answer.svg @@ -0,0 +1,8 @@ + + + Created with Pixso. + + + + + diff --git a/src/assets/svgs/light_support.svg b/src/assets/svgs/light_support.svg new file mode 100755 index 0000000000000000000000000000000000000000..38780af188add51af38b616636aaba4b6b243608 --- /dev/null +++ b/src/assets/svgs/light_support.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/moon.svg b/src/assets/svgs/moon.svg new file mode 100755 index 0000000000000000000000000000000000000000..80735af7d32d4a81020d0a4497140f955d7bde8f --- /dev/null +++ b/src/assets/svgs/moon.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/moon_active.svg b/src/assets/svgs/moon_active.svg new file mode 100755 index 0000000000000000000000000000000000000000..179bcb9e1f24e6fd795f4da1cf2927c7e52b7e13 --- /dev/null +++ b/src/assets/svgs/moon_active.svg @@ -0,0 +1,11 @@ + + + Created with Pixso. + + + + + + + + diff --git a/src/assets/svgs/moon_hover.svg b/src/assets/svgs/moon_hover.svg new file mode 100755 index 0000000000000000000000000000000000000000..f8c2dc9a07823eb601f2bfaec27c658721ecab1a --- /dev/null +++ b/src/assets/svgs/moon_hover.svg @@ -0,0 +1,10 @@ + + + Created with Pixso. + + + + + + + diff --git a/src/assets/svgs/null.svg b/src/assets/svgs/null.svg new file mode 100755 index 0000000000000000000000000000000000000000..3b14e240da8ee3de5cd1fee14f923098b984afb5 --- /dev/null +++ b/src/assets/svgs/null.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/oepkg.svg b/src/assets/svgs/oepkg.svg new file mode 100755 index 0000000000000000000000000000000000000000..64eb2a6aff88b898957c556a02b09c1888eeec31 --- /dev/null +++ b/src/assets/svgs/oepkg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/pkgship.svg b/src/assets/svgs/pkgship.svg new file mode 100755 index 0000000000000000000000000000000000000000..d71e678ce81c2519aba5ff05a1d46a138b44f702 --- /dev/null +++ b/src/assets/svgs/pkgship.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/plus.svg b/src/assets/svgs/plus.svg new file mode 100755 index 0000000000000000000000000000000000000000..e3d6b5a170e3903d0b42558c229990d55742f7a8 --- /dev/null +++ b/src/assets/svgs/plus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/report.svg b/src/assets/svgs/report.svg new file mode 100755 index 0000000000000000000000000000000000000000..6e674911e868f3b28007e031c750161d05fea965 --- /dev/null +++ b/src/assets/svgs/report.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/robot_icon.svg b/src/assets/svgs/robot_icon.svg new file mode 100755 index 0000000000000000000000000000000000000000..80fc1924a9e606d6cc7a4f6f2fafab53c376972b --- /dev/null +++ b/src/assets/svgs/robot_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/search.svg b/src/assets/svgs/search.svg new file mode 100755 index 0000000000000000000000000000000000000000..55445777c03195f8c2464fada93a356cc80ee344 --- /dev/null +++ b/src/assets/svgs/search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/success.svg b/src/assets/svgs/success.svg new file mode 100755 index 0000000000000000000000000000000000000000..676e309048dde792cb3988203f3a4e3bda88aa0b --- /dev/null +++ b/src/assets/svgs/success.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/sun.svg b/src/assets/svgs/sun.svg new file mode 100755 index 0000000000000000000000000000000000000000..22cb2164b79acc038e5c7b82a18586014495c920 --- /dev/null +++ b/src/assets/svgs/sun.svg @@ -0,0 +1,27 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/svgs/sun_active.svg b/src/assets/svgs/sun_active.svg new file mode 100755 index 0000000000000000000000000000000000000000..a8aa687b2de7ce7e66ed40bb63a5028b7acb4115 --- /dev/null +++ b/src/assets/svgs/sun_active.svg @@ -0,0 +1,18 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + diff --git a/src/assets/svgs/sun_hover.svg b/src/assets/svgs/sun_hover.svg new file mode 100755 index 0000000000000000000000000000000000000000..eec104876afd5dab93260e630164be514d78e348 --- /dev/null +++ b/src/assets/svgs/sun_hover.svg @@ -0,0 +1,27 @@ + + + Created with Pixso. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/svgs/support_active.svg b/src/assets/svgs/support_active.svg new file mode 100755 index 0000000000000000000000000000000000000000..d7d13d7e7f58b1b844e521d27e9953b783fe0120 --- /dev/null +++ b/src/assets/svgs/support_active.svg @@ -0,0 +1,13 @@ + + + Created with Pixso. + + + + + + + + + + diff --git a/src/assets/svgs/user.svg b/src/assets/svgs/user.svg new file mode 100755 index 0000000000000000000000000000000000000000..b5b4f8d34c6e1744b3b05f896813a38a430467ed --- /dev/null +++ b/src/assets/svgs/user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svgs/user_icon.png b/src/assets/svgs/user_icon.png new file mode 100755 index 0000000000000000000000000000000000000000..f2a462180ad60b1f34e68b25b5a1436f2e225211 Binary files /dev/null and b/src/assets/svgs/user_icon.png differ diff --git a/src/assets/svgs/wrong.svg b/src/assets/svgs/wrong.svg new file mode 100755 index 0000000000000000000000000000000000000000..57758f36c581f0e6bed4b3caebe58a781abf0b7e --- /dev/null +++ b/src/assets/svgs/wrong.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/assets/svgs/yes.svg b/src/assets/svgs/yes.svg new file mode 100755 index 0000000000000000000000000000000000000000..4d59d70ae3e01e290d5b4878009f22e3e7cd90cb --- /dev/null +++ b/src/assets/svgs/yes.svg @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/src/auto-imports.d.ts b/src/auto-imports.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..1d89ee8c4833d5972293125ae111ea45d41f2e83 --- /dev/null +++ b/src/auto-imports.d.ts @@ -0,0 +1,9 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +export {} +declare global { + +} diff --git a/src/components.d.ts b/src/components.d.ts new file mode 100755 index 0000000000000000000000000000000000000000..3919a57d3ab685800884869e26bbeb4a10515de4 --- /dev/null +++ b/src/components.d.ts @@ -0,0 +1,34 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +declare module 'vue' { + export interface GlobalComponents { + CommonFooter: typeof import('./components/commonFooter/CommonFooter.vue')['default'] + DialoguePanel: typeof import('./components/dialoguePanel/DialoguePanel.vue')['default'] + ElButton: typeof import('element-plus/es')['ElButton'] + ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] + ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup'] + ElDialog: typeof import('element-plus/es')['ElDialog'] + ElForm: typeof import('element-plus/es')['ElForm'] + ElFormItem: typeof import('element-plus/es')['ElFormItem'] + ElInput: typeof import('element-plus/es')['ElInput'] + ElPopover: typeof import('element-plus/es')['ElPopover'] + ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] + ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] + ElTooltip: typeof import('element-plus/es')['ElTooltip'] + EulerDialog: typeof import('./components/EulerDialog.vue')['default'] + PrivacyText: typeof import('./components/commonFooter/PrivacyText.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + SessionCard: typeof import('./components/sessionCard/SessionCard.vue')['default'] + SvgIcon: typeof import('./components/SvgIcon.vue')['default'] + } + export interface ComponentCustomProperties { + vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + } +} diff --git a/src/components/EulerDialog.vue b/src/components/EulerDialog.vue new file mode 100755 index 0000000000000000000000000000000000000000..5852a4f1a883524af84075d2ec3b4e66144525e7 --- /dev/null +++ b/src/components/EulerDialog.vue @@ -0,0 +1,148 @@ + + + + + + + diff --git a/src/components/Message.ts b/src/components/Message.ts new file mode 100755 index 0000000000000000000000000000000000000000..421170f8f8792bb51495f11d393bf974e263275d --- /dev/null +++ b/src/components/Message.ts @@ -0,0 +1,38 @@ +import { ElMessage } from "element-plus"; + +export const infoMsg = (msgInfo:string) => { + ElMessage({ + type:"info", + showClose:true, + dangerouslyUseHTMLString:true, + message:msgInfo, + }) +} + +export const successMsg = (msgInfo:string) => { + ElMessage({ + customClass:"el-message--success", + type:"success", + showClose:true, + class:"el-message--success", + message:msgInfo, + }) +} +export const warningMsg = (msgInfo:string) => { + ElMessage({ + type:"warning", + showClose:true, + class:"el-message--warning", + message:msgInfo, + }) +} + +export const errorMsg = (msgInfo:string) => { + ElMessage({ + type:"error", + showClose:true, + class:"el-message--error", + message:msgInfo, + }) +} + diff --git a/src/components/SvgIcon.vue b/src/components/SvgIcon.vue new file mode 100755 index 0000000000000000000000000000000000000000..f83ae329ff94b701a0574bd673c6e18e09c3dbb1 --- /dev/null +++ b/src/components/SvgIcon.vue @@ -0,0 +1,65 @@ + + + + diff --git a/src/components/commonFooter/CommonFooter.vue b/src/components/commonFooter/CommonFooter.vue new file mode 100755 index 0000000000000000000000000000000000000000..9ffba13b4744559817692e4da5fc273f7c557c2d --- /dev/null +++ b/src/components/commonFooter/CommonFooter.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/src/components/commonFooter/PrivacyText.vue b/src/components/commonFooter/PrivacyText.vue new file mode 100755 index 0000000000000000000000000000000000000000..cfd5a844fb70ae0db72696bca903ff16c12e7944 --- /dev/null +++ b/src/components/commonFooter/PrivacyText.vue @@ -0,0 +1,239 @@ + + diff --git a/src/components/dialoguePanel/DialoguePanel.vue b/src/components/dialoguePanel/DialoguePanel.vue new file mode 100755 index 0000000000000000000000000000000000000000..bb500c0722f344e4675e9a2407df33a77c9c6794 --- /dev/null +++ b/src/components/dialoguePanel/DialoguePanel.vue @@ -0,0 +1,998 @@ + + + + + diff --git a/src/components/dialoguePanel/Flow.vue b/src/components/dialoguePanel/Flow.vue new file mode 100755 index 0000000000000000000000000000000000000000..788ee0b149b91959735b7d1b384660c43a36ad08 --- /dev/null +++ b/src/components/dialoguePanel/Flow.vue @@ -0,0 +1,160 @@ + + + \ No newline at end of file diff --git a/src/components/dialoguePanel/chartsCss.ts b/src/components/dialoguePanel/chartsCss.ts new file mode 100755 index 0000000000000000000000000000000000000000..40691666341e772ff41496b124eb7bce826d9872 --- /dev/null +++ b/src/components/dialoguePanel/chartsCss.ts @@ -0,0 +1,42 @@ +export const Circlelegend = { + icon: "circle", + left: "24px", + top: "30%", + orient: "vertical", + padding: 24, + textStyle: { + fontSize: 12, + width: 200, + rich: { + oneone: { + fontSize: 16, + height: 30, + align: "right", + }, + }, + }, + } + +export const Linetooltip = { + trigger: "axis", + formatter: function (params: any) { + var res = // 字符串形式的html标签会被echarts转换渲染成数据,这个res主要是画的tooltip里的上部分的标题部分 + "

" + + params[0].name; + ("

"); + for (var i = 0; i < params.length; i++) { + //因为是个数组,所以要遍历拿到里面的数据,并加入到tooltip的数据内容部分里面去 + res += `
+ + ${params[i].seriesName} + ${params[i].data} +
`; + } + return res; // 经过这么一加工,最终返回出去并渲染,最终就出现了我们所看的效果 + }, + } + + + diff --git a/src/components/dialoguePanel/type.ts b/src/components/dialoguePanel/type.ts new file mode 100755 index 0000000000000000000000000000000000000000..68ce23927a153898b46be56294af259ef7106718 --- /dev/null +++ b/src/components/dialoguePanel/type.ts @@ -0,0 +1,13 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +export type UserDialoguePanelType = 'user'; +export type RobotDialoguePanelType = 'robot'; + +export type DialoguePanelType = UserDialoguePanelType | RobotDialoguePanelType; diff --git a/src/components/sessionCard/SessionCard.vue b/src/components/sessionCard/SessionCard.vue new file mode 100755 index 0000000000000000000000000000000000000000..a6cae294ddb0896ef0e2eb268a1382601cce7e1e --- /dev/null +++ b/src/components/sessionCard/SessionCard.vue @@ -0,0 +1,329 @@ + + + + + diff --git a/src/components/sessionCard/type.ts b/src/components/sessionCard/type.ts new file mode 100755 index 0000000000000000000000000000000000000000..a18d3609b5125f3e6cb46b67431dac32f120f087 --- /dev/null +++ b/src/components/sessionCard/type.ts @@ -0,0 +1,14 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +export interface SessionItem { + sessionId: string; + title: string; + createdTime?: string | Date; +} diff --git a/src/conf/agreement-en.md b/src/conf/agreement-en.md new file mode 100755 index 0000000000000000000000000000000000000000..88e72dccbef444f6cc08095b1fcd6236b315c974 --- /dev/null +++ b/src/conf/agreement-en.md @@ -0,0 +1,149 @@ +# openEuler Copilot System Service Agreement + +Thank you for choosing the openEuler Copilot System service provided by the OpenAtom Foundation ("Foundation", "we", "our", or "us"). + +This Agreement governs your ("you" or "user") use of the [openEuler Copilot System](https://euler-copilot-web.test.osinfra.cn) website and related services ("Services" or "openEuler Copilot System"). + +**Important:** + +Please carefully read and understand this entire Agreement before using the Services, **especially the provisions on limitations of liability, governing law, and jurisdiction, which are displayed in bold**. If you have any questions or doubts about this Agreement, please contact us at . + +**These Services are intended for adult users.** If you are under 18 years old, please review this Agreement with your legal guardian and obtain their consent before using the Services. By clicking to agree to this Agreement, or by **registering, logging in, or using the Services**, you represent and warrant that you have fully read, understood, and agree to be bound by this Agreement. + +**openEuler Copilot System is currently in beta and is not publicly available.** openEuler Copilot System offers consulting capabilities on OS basics and shell commands, key features of openEuler, openEuler domain data and knowledge, and openEuler O&M solutions. + +**These Services are for internal testing purposes only and may not be used for any other purpose.** Please safeguard your account credentials and do not transfer, lend, or disclose your account, URLs, IP addresses, or any other Service information to any other party. + +We encourage you to provide feedback on any issues encountered during your use of the Services, including software design, functionality, or inappropriate Q&A pairs. + +If you or the entity you represent do not agree to any provision of this Agreement, you should immediately stop using the Services. + +## 1. Definitions + +**1.1 User**: any individual who uses the openEuler Copilot System Services through the openEuler Copilot System website (). This Agreement may refer to users as "you." + +**1.2 openEuler Copilot System**: generative artificial intelligence (AI) Q&A product provided by the Foundation based on large language models. + +**1.3 Input**: content entered by the user in the dialogue box to use the Services. + +**1.4 Output**: text, tables, code, images, and other content output by the Services based on the user's input. + +## 2. Account Management + +**2.1** To use the Services, you must register for a platform account and log in. To comply with laws and regulations regarding identity authentication, enhance your experience, and ensure account security, you must provide a valid mobile phone number or ID card number during registration. You may not transfer, lend, sell, or otherwise make your account or password available to any other party. **You are responsible for all activities that occur under your account, and you bear all consequences arising from the transfer or lending of your account**. + +**2.2** If you are agreeing to this Agreement on behalf of an organization or entity, you represent and warrant that you have the authority to bind that organization or entity to this Agreement. However, you are still required to register separate platform accounts for each user within your organization. Even if you are representing an organization or entity, multiple users within the organization or entity are not permitted to share the same platform account. + +**2.3** You represent and warrant that all registration information provided for your platform account is accurate and up to date. You are solely responsible for any consequences and losses arising from your failure to use your account (including, but not limited to, failure to register successfully or account suspension or cancellation) or during your use due to the information and materials you provide being untrue, untimely, incomplete, inaccurate, or in violation of relevant laws and regulations. + +**2.4** **You are responsible for maintaining the confidentiality of your account information (including account name, password, verification code, etc.). You bear all losses and consequences arising from your improper custody of account information, active disclosure, or attacks, fraud, or other actions by others.** If you discover any unauthorized use of your account to log in and use the Services or any other situation that may lead to the theft or loss of your account, you shall immediately notify us. **You understand that it will take us a reasonable amount of time to act on your request, and we are not liable for any consequences that occur before we take action, unless we are at fault.** + +**2.5** If you violate any provision of this Agreement or if we are unable to verify your account and password, the user content in your account will be inaccessible. We do not guarantee that you will have perpetual access to data or Services accessed through your account and password, nor do we guarantee that we will provide you with copies of data in the event of deletion or loss. You agree to notify us of any known unauthorized use of your account and password. + +**2.6** You understand and agree that the account you set up shall not violate relevant laws and regulations. Your registration information, such as your account name, avatar, and profile, as well as other personal information, shall not contain any illegal or harmful information. You may not open an account in the name of others without their permission (including but not limited to using others' names, avatars, or other methods that may cause confusion) or maliciously register accounts (including but not limited to frequent or bulk registration). You shall comply with relevant laws and regulations during the account registration and usage process and shall not engage in any acts that endanger public interests, harm the legitimate rights and interests of others, or are detrimental to public morality. Otherwise, your account may not be successfully registered or we have the right to cancel it after notifying you. + +**2.7** You may cancel your account and terminate your use of the Services at any time. However, you are still liable for the legal consequences of your account usage prior to cancellation. Please note that if we discover any illegal activities during your use of the Services, we will retain such records in accordance with the law. + +## 3. Service Rules + +### 3.1 Service Use Authorization + +Subject to your compliance with this Agreement, we grant you a revocable, non-exclusive, non-transferable, non-sublicensable right and license to use the Services for your personal, non-commercial use only, and subject to the usage restrictions set forth below. + +### 3.2 Service Use Restrictions + +**3.2.1** You agree that you will not: + +**(1)** Use the Services to engage in any activities that violate laws, regulations, departmental rules, or public order and good morals, or to upload, disseminate, publish, spread, generate, or otherwise make available any information that damages national image, promotes terrorism, disseminates violence, pornography, or false information, or provides assistance to the aforementioned activities. + +**(2)** Decompile, disassemble, reverse engineer, or otherwise attempt to obtain the source code or backend service information related to the Services. + +**(3)** Except as expressly authorized by this Agreement or a separate agreement for a specific Service, copy, disclose, distribute, sell, rent, or lease the Services to any third party, or use the Services for commercial purposes. + +**(4)** Breach, circumvent, bypass, or disable any safety protection network, content protection mechanism, authentication mechanism, digital copyrights management, or data measurement tool of the Services. + +**(5)** Abuse, disrupt, or utilize the Services for any unauthorized use, or attempt to access areas not intended for user access, or upload any malicious software (such as viruses, crashes, worms, Trojan horses, traps, backdoors, or other software of such nature) to servers of the Services, or otherwise interfere with the normal operation of the Services. + +**(6)** Remove any deep synthesis content identification, copyright notices, trademark notices, or other proprietary notices contained in the Services. + +**3.2.2** **You understand and agree that your Input when using the Services does not infringe upon the intellectual property rights, portrait rights, reputation rights, honor rights, privacy rights, personal information rights, or other legitimate rights and interests of any person, nor does it involve any national secrets, trade secrets, important data, or other data that may adversely affect national security or public interests. Otherwise, you shall bear all risks and liabilities arising from such infringement. You shall also be liable for all direct and indirect losses (including but not limited to economic losses, goodwill losses, rights protection expenses, and attorney fees) suffered by us as a result.** + +**3.2.3** To fulfill legal compliance requirements, we have the right to take technical or manual measures to review your use of the Services and related information, including but not limited to reviewing input and output, establishing risk filtering mechanisms, and building illegal content feature libraries. We have the right to take action against violating users in accordance with Article 6 of this Agreement. + +### 3.3 Content Download + +**3.3.1** If you publicly release or disseminate any Output generated by the Services, you shall: (1) actively verify the authenticity and accuracy of the Output to avoid spreading false information; (2) clearly indicate that the Output is generated by AI to inform the public of the synthesized nature of the content; and (3) avoid publishing and disseminating any Output that violates the Service Use Restrictions of this Agreement. + +**3.3.2** The Services provide certain downloadable content, such as code and documents ("Generated Content"). You agree that you will not: + +**(1)** Include any downloaded content in malicious, deceptive, or illegal programs or products, or use it in any illegal or infringing scenarios. + +**(2)** Use any downloaded content for infringing analysis or evidence collection against us or other users' intellectual property rights. + +**(3)** Represent any downloaded Generated Content as human-created content, or remove any identification marks (such as watermarks) carried by the Generated Content. + +**(4)** Use the downloaded Generated Content for commercial purposes. + +**3.3.3** If you illegally use the Services to fabricate or spread false information, we will retain relevant records in accordance with the law and report them to the cybersecurity department and relevant competent authorities. + +### 3.4 Content Provision + +**3.4.1** When using the Services, you may provide Input, including but not limited to text, images, audio, video, code, and comments. We do not claim ownership of any content you provide. + +3.4.2 You represent and warrant that you own all necessary rights to any content you provide and that you are solely responsible for such content. You represent and warrant that the content you provide complies with all applicable laws, regulations, departmental rules, and public order and good morals. You further represent and warrant that you have obtained the content you provide through legal means and have full authorization to use it. + +**3.4.3** If the content you provide is reviewed by us as violating laws, regulations, or this Agreement, or if we receive complaints or reports from third parties regarding such content, we have the right to remove it. + +## 4. Intellectual Property Rights + +**4.1** To the extent permitted by law, you own all rights, title, and interest in and to the Generated Content (excluding Generated Content based on example Input provided by the Services) created through your use of the Services based on the Input you provide, and you are solely responsible for such Generated Content. You hereby grant us a worldwide, perpetual, free, irrevocable, non-exclusive, sublicensable license to reproduce, use, publicly display, distribute, and modify such Generated Content. + +**4.2** Due to the nature of machine learning, you acknowledge that the Generated Content you create using the model or foundation model online experience services may be identical or substantially similar to Generated Content created by other users using the same services. You further acknowledge that Generated Content requested and created for other users does not belong to you. + +**4.3** The Generated Content you create using the Services may contain links or information referring to third-party websites or services. These websites or services are not owned or controlled by us. When you access third-party websites or participate in third-party services, you understand that doing so is at your own risk and that we are not responsible for such risks. We encourage and advise you to carefully review the terms of service, privacy policies, and other relevant agreements of any third-party websites or services that you visit or use. + +## 5. Personal Information Protection + +**5.1** We are well aware of the importance of personal information to you, and your trust is of utmost importance to us. We will strictly comply with legal and regulatory requirements, take appropriate security protection measures, and are committed to protecting your personal information. + +**5.2** During your use of the Services, we may request you to provide, and we may also actively collect, certain necessary personal information from you. You can learn more about how we collect, use, and protect your personal information in detail through our [Privacy Policy](https://www.openeuler.org/en/other/privacy/). + +## 6. Complaints and Appeals + +**6.1** Complaints: If you find that the Services infringe upon your intellectual property rights or other legitimate rights and interests, please submit an _Infringement Complaint Notice_ to us via email. The notice should include the following information: + +**(1)** Complainant information: Name, identification information, and contact details of the complainant (for individuals, please provide a valid identification document; for enterprises, please provide a business license or other relevant supporting documents). + +**(2)** Infringing service information: Content and web address of the alleged infringement. + +**(3)** Reasons for the infringement complaint: Specific type of right infringed (such as trademark rights and copyrights) and a brief explanation of the reasons for the infringement. + +(4) Supporting materials for the infringement complaint: Including but not limited to proof of ownership of the trademark rights, copyrights, and/or other legally enforceable rights in the allegedly infringing content. + +Upon receipt of the _Infringement Complaint Notice_ via email, we will promptly review whether the submitted materials constitute preliminary evidence of infringement. If preliminary evidence is established, we will take prompt action, including but not limited to timely measures to stop the generation, transmission, and removal of the infringing content. + +**6.2** Appeals: If you believe that we have improperly restricted your ability to use the Services, you can send the relevant appeal materials to . The materials required for the appeal should include at least your account information, a copy of your ID card or passport (for individuals), a copy of your business registration certificate (for entities), the current status of your account, the specific circumstances that led to the action taken against your account, and the measures you request us to take to restore your ability to use the Services. We will notify you of the appeal results by email. + +## 7. Disclaimer and Liability for Breach + +**7.1** We are committed to providing safe, stable, and continuous Services to ensure normal user experience. However, due to technological limitations and the special nature of AI, we expressly remind you that we cannot guarantee the compliance, accuracy, and completeness of the content generated by the Services. **You should exercise your own judgment regarding the Output generated by the Services and bear all risks arising from its use. We remind you that, except as expressly provided by law, we cannot and will not be liable for any loss or damage caused by the aforementioned risks.** + +**7.2** **The Output provided by the Services does not constitute professional advice and cannot replace professional practitioners in fields such as technology, law, or finance in answering your questions. The relevant opinions are only for your reference based on the limited data accessible to the algorithm and do not represent our position or views.** + +**7.3** We are not liable for any legal liabilities and risks arising from your violation of the provisions or commitments stipulated in Article 3 of this Agreement. If your breach of this Agreement infringes upon the legitimate rights and interests of any third party, resulting in any complaints, reports, claims, or lawsuits against us and/or our partners, you are obligated to take active measures (including but not limited to actively responding with evidence and participating in litigation) to ensure that we and our partners are exempt from or promptly relieved of such predicament. If we and/or our partners suffer any direct or indirect losses to reputation, goodwill, or property as a result, you shall be fully liable for damages. + +**7.4** If you violate the provisions of Article 3 of this Agreement, we have the right to take reasonable measures that we deem appropriate, including but not limited to warnings, feature restrictions, suspension or termination of Services, deletion of illegal and infringing information, and account suspension, and to retain relevant records. If you have any objections to the handling results, you can file an appeal with us in accordance with the provisions of Article 9.2, and we will promptly accept, process, and provide feedback. + +## 8. Governing Law and Jurisdiction + +**8.1** The formation, execution, and interpretation of this Agreement, as well as the resolution of any disputes arising therefrom, shall be governed by the laws of the People's Republic of China. + +**8.2** Any dispute arising from the signing, performance, or interpretation of this Agreement shall be settled through friendly negotiation between the parties. If negotiation fails, either party has the right to file a lawsuit with the court having jurisdiction over the place where the OpenAtom Foundation is located. + +## 9. Amendment and Termination + +**9.1** Your acceptance of this Agreement constitutes your acceptance of any and all amendments made by us to any provision of this Agreement at any time. We reserve the right to amend this Agreement at any time, and the updated Agreement will be published through appropriate means, such as posting on our official website. **The updated Agreement will supersede the original provisions upon publication. Please refer to our official website for the latest version of the Agreement. If you do not agree to the amended Agreement, please immediately stop using the Services. Your continued use of the Services will be deemed as your acceptance of the amended Agreement.** + +Updated on: April 30, 2024 + +Effective date: April 30, 2024 diff --git a/src/conf/agreement-tip.md b/src/conf/agreement-tip.md new file mode 100755 index 0000000000000000000000000000000000000000..df3651dd2aa4b0657c43630a86e4f074fa1d8b28 --- /dev/null +++ b/src/conf/agreement-tip.md @@ -0,0 +1,7 @@ +openEuler Copilot System(内测版)旨在让内测用户提前体验openEuler的智能化能力,帮助发现和修复版本质量、可用性及易用性问题,共同将版本做得更加完善。如果您发现任何问题(包括软件设计、软件功能、不合适的问答对等),欢迎您反馈您的宝贵意见! + +**本服务仅限于内测用户学习研究、内部测试目的使用**。您不得将本服务用于生产环境或任何其他商业目的,否则您自行承担由此造成的所有后果和责任。 + +内测期间,除正常反馈问题外,应遵守内测用户保密规则:禁止在任何地方传播包括但不限于系统界面、功能点等参与内测得知的有关本服务的各种非公开信息。 + +***以上规则需严格遵守,如有违反,我们有权撤销您的内测资格,情节严重造成恶劣影响或损失者,我们将保留追究其责任的权利。*** \ No newline at end of file diff --git a/src/conf/agreement.md b/src/conf/agreement.md new file mode 100755 index 0000000000000000000000000000000000000000..4d116da0621f25bb4486edfc2a8623ab9fc92c6a --- /dev/null +++ b/src/conf/agreement.md @@ -0,0 +1,153 @@ +# openEuler Copilot System 服务协议 + + +欢迎您使用开放原子开源基金会(下文简称“基金会”或“我们”)提供的 openEuler Copilot System 服务! + +本协议约束您(使用者)对[openEuler Copilot System](https://euler-copilot-web.test.osinfra.cn)网站等相关服务(以下简称“本服务”或“openEuler Copilot System”)的使用。 + +**重要提示:** + +请您在使用本服务之前认真阅读、充分理解本协议的全部条款,**尤其是责任限制或排除、法律管辖和适用等加粗显示的条款**。如您对本协议有任何疑问,请通过contact@openeuler.io联系我们。 + +**本服务主要面向成人**。如果您未满 18 周岁,请在法定监护人陪同下阅读本协议,并在征得法定监护人的同意后使用本服务。当您阅读并点击同意本协议**或您的注册、登录、使用等行为将视为您**已充分阅读、理解并接受本协议的全部内容。 + +openEuler Copilot System(内测版)旨在让内测用户提前体验openEuler的智能化能力,帮助发现和修复版本质量、可用性及易用性问题,共同将版本做得更加完善。如果您发现任何问题(包括软件设计、软件功能、不合适的问答对等),欢迎您反馈您的宝贵意见! + +**本服务仅限于内测用户学习研究、内部测试目的使用**。您不得将本服务用于生产环境或任何其他商业目的,否则您自行承担由此造成的所有后果和责任。 + +内测期间,除正常反馈问题外,应遵守内测用户保密规则:禁止在任何地方传播包括但不限于系统界面、功能点等参与内测得知的有关本服务的各种非公开信息。 + +***以上规则需严格遵守,如有违反,我们有权撤销您的内测资格,情节严重造成恶劣影响或损失者,我们将保留追究其责任的权利。*** + +如果您或您所代表的实体不同意本协议的任何内容,您应该立即停止使用本服务。 + +## 第 1 条 定义 + +**1.1 用户** :指通过https://euler-copilot-web.test.osinfra.cn网站使用 openEuler Copilot System 服务的自然人。本协议中可称为“使用者”或“您”。 + +**1.2 openEuler Copilot System** :指基金会基于大语言模型提供的生成类人工智能问答产品。 + +**1.3 输入** : 指用户为使用本服务在对话框输入的内容。 + +**1.4 输出** : 指本服务根据用户输入而相应输出的文字、表格、代码和图片等内容。 + +## 第 2 条 账号管理 + +**2.1** 为使用本服务,您需要注册一个平台帐户并登录您的账户。为落实国家法律法规的有关实名认证的要求,使您更好地本服务,保障您的账号安全,您在注册时需要向我们提供真实的手机号码或身份证号。您不应将账号或密码转让、出借、销售或以任何脱离您控制的形式交由他人使用,**您对使用您的账号发生的所有活动负责,且转让、出借账号导致的任何后果均由您本人承担**。 + +**2.2** 如果您代表的组织或实体同意本协议,则您声明并保证您有权代表该组织或实体同意本协议并将其约束于本协议, 但您仍然需要为您的组织中的每个用户独立注册平台账户。即使您代表组织或实体,也不允许组织或实体内多个用户共用同一个平台账户。 + +**2.3** 您声明并保证有关平台账户的所有注册信息的准确性和最新性。因您填写的信息、资料不真实、不及时、不完整、不准确或违反国家法律法规相关规定的,您应承担您不能使⽤账户(不能注册成功、或账户被冻结、注销)或您在使⽤过程中的后果和损失。 + +**2.4** **您应该自行保管好您的账号信息(包括账号、密码、验证码等)。因您对账号信息保管不当、主动泄露或遭受他人攻击、诈骗等行为导致的损失及后果,均由您自行承担**。如发现任何未经授权使用您账号登录使用本服务或其他可能导致您账号遭窃、遗失的情况,您应当立即通知我们。**您理解我们对您的请求采取行动需要合理时间,除我们存在过错外,我们对在采取行动前已经产生的后果不承担责任**。 + +**2.5** 如果您违反本协议的内容或我们无法验证您的账户和密码,您账户中的用户内容将无法访问。我们不保证您可以永久访问通过您的账户和密码使用的数据或服务,也不保证在数据被删除或丢失时向您提供副本。您同意将任何已知的未经授权使用您的账户和密码的情况通知我们。 + +**2.6** 您理解并承诺,您所设置的账号不得违反国家法律法规相关规定,您的账号名称、头像和简介等注册信息及其他个人信息中不得出现违法和不良信息,未经他人许可不得用他人名义(包括但不限于冒用他人姓名、名称、字号、头像等足以让人混淆的方式)开设账号,不得恶意注册账号(包括但不限于频繁注册、批量注册账号等行为)。您在账号注册及使用过程中需遵守相关法律法规,不得实施任何侵害国家利益、损害其他公民合法权益、有害社会道德风尚的行为。否则您的账户可能不能注册成功或我们有权经通知您后主动予以注销。 + +**2.7** 您可以随时注销您的账号并终止使用本服务,但您仍需对您注销前的账号使用行为承担相应法律责任。请注意,若我们发现您在使用本服务过程中存在违法行为,我们将依法保存该等记录。 + +## 第 3 条 服务规范 + +### 3.1 服务使用授权 + +基于您对本服务的使用,我们特此向您授予可撤销、非排他性、不可转让、无分许可的权利许可使用本服务,但仅供您个人非商业用途的使用,且需遵守下文所述的使用限制。 + +### 3.2 服务使用限制 + +**3.2.1** 一旦您使用本平台的任何内容或服务,您承诺,您不得: + +**1)**利用本服务从事任何违反法律法规、部门规章或公序良俗的行为,利用服务上传、散播、发布、传播、发表、生成任何涉及损害国家形象、恐怖、暴力、色情、虚假等任何违反法律法规要求的信息,或为上述行为提供帮助; + +**2)** 反编译、反汇编、反向工程或以其他方式尝试获取本服务相关的源代码或后端服务的信息; + +**3)** 除本协议或某一服务有单独协议明确授权外,复制、披露、分发、出售、出租或租赁本服务给任何第三方,或者或以商业化目的使用本服务; + +**4)** 突破、避开、绕过或禁用本服务的任何安全防护网、内容保护机制、身份验证机制、数字版权管理或数据度量工具等; + +**5)** 滥用、破坏或利用本服务进行任何未经授权的使用,或尝试访问不适合用户使用的区域,或向本服务的服务器上传任何恶意软件(例如病毒、死机、蠕虫、特洛伊木马、陷阱、后门或其他此类性质的软件)或者以其他方式干扰本服务的正常运行; + +**6)** 删除本服务中包含的任何深度合成内容标识、版权声明、商标声明或其他所有权声明。 + +**3.2.2** **您理解并承诺,您在使用本服务时的输入不侵犯任何人的知识产权、肖像权、名誉权、荣誉权、姓名权、隐私权、个人信息权益等合法权益,不涉及任何国家秘密、商业秘密、重要数据或其他可能会对国家安全或者公共利益造成不利影响的数据,否则由此产生的侵权风险和责任由您承担。我们由此遭受的全部直接和间接损失(包括但不限于经济、商誉、维权支出、律师费等损失)也同样由您承担。** + +**3.2.3** 为履行法定合规要求,我们有权采取技术手段或人工手段对用户使用本服务的行为及信息进行审查,包括但不限于对输入和输出进行审查、建立风险过滤机制、建立违法内容特征库等。对于违规用户,我们有权按照本协议第 6 条的规定进行处置。 + +### 3.3 内容下载 + +**3.3.1** 如果您对外发布或传播本服务生成的输出,您应当:(1)主动核查输出内容的真实性、准确性,避免传播虚假信息;(2)以显著方式标明该输出内容系由人工智能生成,以向公众提示内容合成的情况;(3)避免发布和传播任何违反本协议使用规范的输出内容。 + +**3.3.2** 本服务提供可供您下载的某些内容,例如可供下载的代码、文档等内容(下称“生成内容”)等,对于您下载的本平台的内容,您承诺,您不得: + +**1)** 将所下载的内容包括在恶意、欺骗或非法的计划或产品中,或者用于任何违法违规场景; + +**2)** 将所下载的内容用于针对我们或其它用户的知识产权侵权分析、取证; + +**3)** 将所下载的生成内容表示为人为创作的内容,或移除生成内容携带的标志标识(例如:水印等); + +**4)** 基于商业用途使用所下载的生成内容。 + +**3.3.3** 如果您⾮法利⽤本服务编造、传播虚假信息的,我们会依法保存有关记录,并向⽹信部⻔和有关主管部⻔报告。 + +### 3.4 内容提供 + +**3.4.1** 您在使用本服务时,您可以提供输入,包括但不限于文字、图片、音频、视频、代码、评论等。我们为不会改变您提供的内容的所有权。 + +**3.4.2** 您承诺您对提供的任何内容拥有相应的权利,并对您提供的内容承担全部责任。您承诺并保证您提供的内容满足法律法规、部门规章以及公序良俗的要求。您承诺并保证您提供的内容,是您通过合法途径取得并获得充分授权对其进行使用的。 + +**3.4.3** 若您提供的内容被我们审核为违反法律、法规或本协议的内容或者受到第三方的投诉或举报,我们有权将您提供的内容移除。 + +## 第 4 条 知识产权 + +**4.1** 在法律允许的范围内,您在使用本服务时基于您提供的输入产生的生成内容(不包含基于本服务提供的示例性输入内容产生的生成内容)的所有权和相关权益归您所有,并且您应该对该生成内容负责。您同意在此授予我们全球范围内的、永久性的、免费的、不可撤销的、非排他的以及可分许可的复制、使用、公开展示、分发、修改等许可。 + +**4.2** 由于机器学习的性质,您同意您使用模型或大模型在线体验服务时产生的生成内容可能和其他用户使用相应服务时产生的生成内容一致或实质性相似,由其他用户请求并为其他用户产生的生成内容不属于您拥有所有权的内容。 + +**4.3** 您在使用本服务时产生的生成内容可能包含指向第三方网站或服务的链接或信息,这些网站或服务并非由我们拥有或控制。当您访问第三方网站或参与第三方服务时,您了解这样做是存在风险的,并且我们不承担此类风险。我们鼓励并建议您在跳转第三方网站时注意并阅读您访问或使用的第三方网站或服务条款、隐私政策和其它相关协议 + +## 第 5 条 个人信息保护 + +**5.1** 我们深知个⼈信息对您的重要性,您的信赖对我们⾮常重要,我们将严格遵守法律法规要求采取相应的安全保护措施,致⼒于保护您的个⼈信息。 + +**5.2** 您在参与本服务的过程中我们可能会要求您向我们提供、同时我们也可能会主动收您的⼀些必要个⼈信息。你可通过[《隐私政策》](https://www.openeuler.org/zh/other/privacy/)详细了解我们如何收集、使⽤、保护您的个⼈信息。 + +## 第 6 条 投诉和申诉 + +**6.1** 投诉。如发现本服务侵犯了您的知识产权或其他合法权益,请填写并邮件反馈《侵权投诉通知书》,通知书建议包含以下内容: + +**1)**投诉方信息:投诉方名称、证件信息和联系方式等(如为个人,可提供有效身份证明文件,如为企业,可提供企业营业执照等相关证明文件); + +**2)**侵权服务信息:涉嫌侵权的内容和网络地址; + +**3)**侵权理由:具体投诉的权利类型(如商标权、著作权),并简要说明侵权理由; + +**4)**侵权证明材料:包括但不限于投诉方对涉嫌侵权内容拥有商标权、著作权和/或其他依法可以行使权利的权属证明等。 + +在收到投诉方邮件反馈的《侵权投诉通知书》后,我们将及时审视相关材料能否形成侵权的初步证据。若已形成初步证据,我们将及时进行处理,包括及时采取停止生成、停止传输、消除等合理处置措施。 + +**6.2** 申诉。如果您认为我们不恰当地限制了您使用本服务的能力,您可以将相关申诉材料发送至该邮箱:contact@openeuler.io申诉所需的材料至少包括您的账号信息、身份证或护照复印件(对自然人)、单位登记证明复印件(对单位)、账号当前状态、账号因何种使用情形被采取措施以及您希望我们采取何种措施恢复您使用本服务的能力。申诉结果我们将以邮件方式通知您。 + +## 第 7 条 免责声明与违约责任 + +**7.1** 我们致力于提供安全、稳定、持续的服务,保障用户正常使用,因技术的局限性和⼈⼯智能的特殊性,我们特别提醒您,我们不能保证本服务⽣成内容合规、准确和完整。**您应对本服务中的输出自行加以判断,并承担因使用内容引起的所有风险。我们提示您,除法律有明确规定外,我们无法也不会对前述风险而导致的任何损失或损害承担责任**。 + +**7.2** **本服务下的输出不代表专业意见,不能代替如技术、法律、金融等专业领域从业人员向您解答对应疑问。相关观点也仅限于算法所触达有限数据呈现的供您参考的结果,并不代表我们的立场和观点**。 + +**7.3** 我们不承担因您违反本协议第 3 条约定或承诺⽽引发的任何法律责任和⻛险。当您违约使⽤本服务侵犯了第三⽅的合法权益⽽导致我们或/及我们的合作⽅遭受任何投诉、举报、索赔或诉讼,您有义务积极采取措施(包括但不限于积极举证回应、参与诉讼),以保证我们和我们的合作⽅免受或尽快摆脱该困境。当我们或/及我们的合作⽅因此遭受任何名誉、声誉或财产上的直接或间接损失时,您负有全部的损害赔偿责任。 + +**7.4** 当您违反本协议第 3 条约定约定时,我们有权采取警示、限制功能、暂停或终止提供服务、删除违法违规信息、锁定账号等我们认为合理的处理措施,并保存有关记录。对处理结果存在疑议的,用户可根据 9.2 条之规定向我们进行申诉,我们将及时受理并进行处理和反馈。 + +## 第 8 条 法律管辖和适用 + +**11.1** 本协议的订立、执行和解释及争议的解决均应适用中华人民共和国大陆地区法律。 + +**11.2** **本协议的签订、履行或解释发生争议,双方应努力友好协商解决。如协商不成,任何一方均有权向开放原子开源基金会住所地有管辖权的法院起诉**。 + +## 第 9 条 本协议的更新与终止 + +**9.1** 您对本协议的接受包括接受我们对本协议任何条款随时所做的任何修改。我们有权随时修改本协议,更新后的协议将通过官方网站公布等适当的方式进行公布。**一旦公布即代替原协议条款,请您自行在官方网站查阅最新版协议条款。如您不接受修改后的协议,请您立即停止使用本服务。您继续使用本服务将被视为您已接受了修改后的协议**。 + + +更新日期:2024 年 4 月 30 日 + +生效日期:2024 年 4 月 30 日 diff --git a/src/conf/policy-en.md b/src/conf/policy-en.md new file mode 100755 index 0000000000000000000000000000000000000000..2dc05b4c83b7eda5dabdcd28f7802e06c8ff80a7 --- /dev/null +++ b/src/conf/policy-en.md @@ -0,0 +1,132 @@ +# openEuler Copilot System Privacy Policy + +The OpenAtom Foundation ("Foundation", "we", "our", or "us") understands the importance of your privacy and fully respects it. Please read this Privacy Statement ("Statement") carefully before you submit your personal data to us. If you have any questions about how we process your personal data, please feel free to contact us. + +## 1\. How We Collect and Process Your Personal data + +If you only browse the general content of the openEuler community website ("this website"), we usually do not require you to provide personal data. However, we will collect your personal data in the following cases: + ++ **a. Account Service.** When you register an openEuler community account or use our services, we will collect information you provide, such as your phone number and email address. ++ **b. Forum Service.** When you enable device location and use our location-based services, we will collect information about your location, including: + + Your geolocation information collected through GPS, Wi-Fi, or similar technologies when you use our services through a mobile device with location functionality enabled; + + You can stop the collection of your geolocation information by disabling the location function. ++ **Log Information**: We use cookies, identifiers, and similar technologies to collect information about how you interact with our services, including **data about your device, browsing activities, and clicks**. This information is stored in log files and helps us provide personalized experience and maintain security. You can manage or disable these technologies in your browser settings. + +## 2\. How We Use Cookies and Similar Technologies + +**2.1 How and How Long We Store Information** + ++ To ensure our website works properly, we may at times place cookies on your computer or mobile device. A cookie is a small data file placed on your computer or mobile device that facilitates your access to a website. The content of a cookie can be retrieved or read only by the server that creates the cookie. We use cookies and similar technologies for understanding how you interact with our websites, helping you efficiently browse pages, storing and honoring your preferences, and improving your browsing experience. ++ Generally, we will only store your personal data for as long as it is necessary to fulfill the purposes described in this Statement or as required by law. + +**2.2 Types of Cookies** + ++ Strictly Necessary Cookies: When you use the website, cookies ensure that your visit to the website is as smooth and secure as possible. ++ Statistical Analysis Cookies: We collect information about your use of the service, including your single or multiple visits. These cookies help us understand how the service is performing and being used. We use statistical analysis plugins provided by Baidu. + +**2.3 Notice of Product or Service Discontinuation** + ++ In the event that our products or services are discontinued, we will notify you by push notification, announcement, or other means and delete or anonymize your personal data within a reasonable time, unless otherwise provided by laws and regulations. + +## 3\. How We Share Your Personal Data + +Sharing refers to the process by which we provide personal data to a third party and we and the third party each process the personal data independently. We will not share your personal data with any third party without your consent, except as otherwise provided in this Statement or under the following circumstances: + +## 4\. How Long We Retain Your Personal Data + +We may use the information we collect in the process of providing you with services for the following purposes: + ++ We will retain your personal data for as long as is necessary to fulfill the purposes described in this Statement, unless a longer retention period is required by laws or requested by you. ++ In general, we will store or retain your personal data for the retention period from the date we obtain it when you use our community services, in accordance with applicable legal requirements or the terms of the service agreement. If your personal data is beyond the retention period and we are not legally required to continue processing your specific personal data, we will delete or anonymize your personal data in accordance with applicable legal requirements. ++ For example, the IP address, access timestamp, access source, accessed pages, access status, accessed resource size, OS, system language, browser type, browser language, browser version, and server type and version information collected for service optimization will be automatically deleted after 10 days. ++ For example, when the community no longer displays you as a member of an openEuler User Group, we will delete your personal data (avatar, name, email address, company/school, position, personal profile) within one month. + +## 5\. How We Protect Your Personal Data + +We take the security of your personal data seriously. We take appropriate physical, organizational, and technical measures to protect your personal data. For example, we use encryption technologies to ensure the confidentiality of data; we implement protection mechanisms to protect data from attacks. We deploy access control mechanisms to ensure that only authorized personnel can access your personal data. In addition, we hold security and privacy protection training. + +In a word, we are committed to protecting your personal data. Nevertheless, no security measure is perfect and no product, service, website, data transfer, computing system, or network connection is absolutely secure. + +## 6\. Your Rights to Access or Control Your Personal Data + +In accordance with applicable laws and regulations, you may have the following rights regarding your personal data: + ++ Access the personal data we hold about you and obtain copies thereof; ++ Request us to update or correct your personal data; ++ Request us to erase your personal data; ++ Object to our processing of your personal data; ++ Restrict our processing of your personal data; ++ Lodge a complaint with the competent data protection authority. + ++ **Location Information**: When you enable device location and use our location-based services, we will collect information about your location, including: + + Your geolocation information collected through GPS, Wi-Fi, or similar technologies when you use our services through a mobile device with location functionality enabled; + + You can stop the collection of your geolocation information by disabling the location function. ++ **Log Information**: We use cookies, identifiers, and similar technologies to collect information about how you interact with our services, including **data about your device, browsing activities, and clicks**. This information is stored in log files and helps us provide personalized experience and maintain security. You can manage or disable these technologies in your browser settings. + +## 2\. Information Storage + +**2.1 How and How Long We Store Information** + ++ We store your information in a secure manner, including local storage (such as data caching using an application), databases, and server logs. ++ Generally, we will only store your personal data for as long as it is necessary to fulfill the purposes described in this Statement or as required by law. + +**2.2 Where We Store Information** + ++ We will ensure that users' personal data collected in China is stored in China in accordance with laws and regulations. ++ We do not currently transfer or store your personal data outside of China. If we need to transfer or store your personal data outside of China in the future, we will inform you of the purpose of the cross-border transfer or storage, the recipient, the security measures, and the security risks, and obtain your consent. + +**2.3 Notice of Product or Service Discontinuation** + ++ In the event that our products or services are discontinued, we will notify you by push notification, announcement, or other means and delete or anonymize your personal data within a reasonable time, unless otherwise provided by laws and regulations. + +## 3\. Information Security + +We use a variety of security technologies and procedures to prevent the loss, misuse, unauthorized access to, or disclosure of information. For example, in some services, we will use encryption technology (such as SSL) to protect the personal data you provide. However, please understand that due to technical limitations and the possible existence of various malicious means, in the Internet industry, even with the best efforts to strengthen security measures, it is not possible to always guarantee 100% security of information. You need to understand that the systems and communication networks you use to access our services may experience problems due to factors beyond our control. + +## 4\. How We Use Personal Data + +We may use the information we collect in the process of providing you with services for the following purposes: + ++ To provide you with services; ++ For identity verification, customer service, security protection, fraud monitoring, archiving, and backup purposes in connection with our provision of services to ensure the security of the products and services we provide to you; ++ To help us design new services and improve our existing services; ++ To allow us to better understand how you access and use our Services so that we can respond to your personalized needs in a targeted manner, such as language settings, location settings, personalized help services and instructions, or otherwise respond to you and other users; ++ To provide you with more relevant advertising instead of generic advertising; ++ To evaluate and improve the effectiveness of our in-service advertising and other promotional and marketing activities; ++ For software authentication or software upgrade management; and ++ To enable you to participate in surveys about our products and services. + +## 5\. Information Sharing + +Currently, we do not proactively share or transfer your personal data to any third parties. If there are other circumstances in which we share or transfer your personal data or you need us to share or transfer your personal data to a third party, we will directly or confirm that the third party has obtained your explicit consent for such actions. + +In order to serve advertisements, evaluate and optimize the effectiveness of advertisements, and for other purposes, we need to share some of your data with third-party partners such as advertisers and their agents, requiring them to strictly comply with our data privacy protection measures and requirements, including but not limited to processing according to data protection agreements, letters of commitment, and relevant data processing policies, avoiding the identification of personal identities, and ensuring privacy security. + +We will not share information that can be used to identify you personally (such as your name or email address) with partners without your explicit permission. + +We will not publicly disclose the personal data we collect. If we must publicly disclose it, we will inform you of the purpose of the disclosure, the type of information disclosed, and any sensitive information that may be involved, and obtain your explicit consent. + +As our service continues to develop, we may engage in mergers, acquisitions, asset transfers, or other transactions. We will inform you of such circumstances and continue to protect or require the new controller to continue to protect your personal data in accordance with laws and regulations and no less than the standards required by this Privacy Policy. + +In addition, according to relevant laws, regulations, and national standards, we may share, transfer, or publicly disclose the following personal data without your prior consent: + ++ Information that is directly related to national security or national defense; ++ Information that is directly related to public safety, public health, or major public interests; ++ Information that is directly related to criminal investigation, prosecution, trial, and judgment execution; ++ Information for the purpose of safeguarding major legitimate rights and interests, such as life and property of personal data subjects or others, when obtaining the consent is not feasible; ++ Information that is disclosed by the personal data subject to the public; and ++ Information that is legally disclosed to the public, such as legitimate news reports and government information disclosure channels. + +## 6\. Your Rights + +During your use of our services, we may provide you with settings depending on the specific product so that you can inquire about, delete, correct, or withdraw your relevant personal data. You can refer to the respective instructions. In addition, we have also set up complaint and reporting channels, and your opinions will be handled in a timely manner. If you are unable to exercise your personal data subject rights through the above channels and methods, you can submit your request through the contact information provided in this Privacy Policy. We will respond in accordance with the provisions of laws and regulations. + +You can request to cancel your account when you decide to stop using our products or services. Upon cancellation of your account, we will delete or anonymize your personal data unless otherwise provided by laws and regulations. + +## 7\. Changes + +We may amend the terms of this Privacy Policy from time to time. We will notify you of the new Privacy Policy and inform you of the effective date when changes are made. Please carefully read the updated Privacy Policy. **If you continue to use our services, you agree to our processing of your personal data in accordance with the updated Privacy Policy.** + +## 8\. Protection of Minors + +We encourage parents or guardians to guide minors under the age of eighteen in their use of our Services. We recommend that minors encourage their parents or guardians to read this Privacy Policy, and that minors seek the consent and guidance of their parents or guardians before submitting personal data. diff --git a/src/conf/policy.md b/src/conf/policy.md new file mode 100755 index 0000000000000000000000000000000000000000..559ab236cfe4a47c11a74e066d3350242690e54d --- /dev/null +++ b/src/conf/policy.md @@ -0,0 +1,131 @@ +# openEuler Copilot System隐私政策 + +开放原子开源基金会(下文简称“我们”或“基金会”)深知您的隐私对您的重要性,并充分尊重您的隐私。在向我们提交您的个人信息之前,请您仔细阅读本《隐私政策声明》(以下简称“本声明”)。如果您对于我们处理您的个人信息的方式有任何疑问,欢迎与我们联系。 + +## 1\. 我们如何收集和处理您的个人信息 + +如果您仅仅浏览 openEuler 社区网站(以下简称“本网站”)的一般性内容,我们通常并不要求您提供个人信息,但在以下情形,我们会相应收集您的个人信息: + ++ **a.账号服务**,您在注册账户或使用我们的服务时,向我们提供的相关个人信息,例如电话号码、电子邮件等。 ++ **b.论坛服务**,指您开启设备定位功能并使用我们基于位置提供的相关服务时,收集的有关您位置的信息,包括: + + 您通过具有定位功能的移动设备使用我们的服务时,通过GPS或WiFi等方式收集的您的地理位置信息; + + 您可以通过关闭定位功能,停止对您的地理位置信息的收集。 ++ **日志信息**,指您使用我们的服务时,系统可能通过cookies、标识符及相关技术收集的信息,包括您的**设备信息**、**浏览信息**、**点击信息**,并将该等信息储存为日志信息,为您提供个性化的用户体验、保障服务安全。您可以通过浏览器设置拒绝或管理cookie、标识符或相关技术的使用。 + +## 2\. 我们如何使用 Cookie 及类似技术 + +**2.1 信息存储的方式和期限** + ++ 为确保网站正常运转,我们有时会在计算机或移动设备上存储 Cookie。Cookie是访问网站时放置在您的计算机或移动设备上的小型数据文件。Cookie 的内容只能由创建它的服务器检索或读取。Cookie服务于不同的目的,例如帮助我们了解网站如何被使用,让您高效地浏览页面,记住您的偏好并总体上改善您的浏览体验。 ++ 一般情况下,我们只会在为实现服务目的所必需的时间内或法律法规规定的条件下存储您的个人信息。 + +**2.2 我们使用二种类型的Cookie** + ++ 严格必要的Cookie: 当您使用网站时,Cookie将确保您对该网站的访问尽可能顺利、安全; ++ 统计分析Cookie:我们收集关于您使用服务的信息,包括您的单次或多次访问,这些Cookie帮助我们了解服务是如何运行、使用的。我们使用百度提供的统计分析插件。 + +**2.3 产品或服务停止运营时的通知** + ++ 当我们的产品或服务发生停止运营的情况时,我们将以推送通知、公告等形式通知您,并在合理期限内删除您的个人信息或进行匿名化处理,法律法规另有规定的除外。 + +## 3\. 我们如何共享您的个人信息 + +共享是指我们向第三方提供个人信息,且我们和第三方分别对个人信息进行独立处理的过程。除非您的同意,我们不会向第三方共享您的个人信息,但以下情况或本声明规定的情形除外: + +## 4\. 我们将保留多久您的个人信息 + +我们可能将在向您提供服务的过程之中所收集的信息用作下列用途: + ++ 我们将会在达成本声明所述目的所需的期限内保留您的个人信息,除非按照法律要求或您的要求需要延长保留期。 ++ 一般而言,我们会自您使用我们的社区服务时获取您的个人信息之日起,根据可适用法律的要求或服务协议的约定,在留存期限内存储或保留您的个人信息。在您的个人信息超出保留期限后,且没有法律要求我们继续处理您的特定个人信息的情况下,我们将会根据可适用法律的要求删除您的个人信息,或进行匿名化处理。 ++ 例如为了服务优化,基于统计访问数量目的收集的 IP 地址、访问时间戳、访问来源、访问页面、访问状态、访问资源大小、操作系统、系统语言、浏览器类型、浏览器语言、浏览器版本、访问社区所用服务器类型版本信息会保存 10 天后自动删除。 ++ 使我们更加了解您如何接入和使用我们的服务,从而针对性地回应您的个性化需求,例如语言设定、位置设定、个性化的帮助服务和指示,或对您和其他用户作出其他方面的回应; ++ 例如当社区不再将您作为社区城市用户组的成员展示,我们将在 1 个月内删除之前为了展示您的成员身份而收集的您的个人数据(头像、姓名、邮箱、公司名称、职位、学校、个人简介)。 + +## 5\. 我们将如何保护您的个人信息 + +我们重视您的个人信息安全。我们采用适当的物理、管理和技术保障措施来保护您的个人信息。例如,我们会使用加密技术确保信息的机密性;我们会使用保护机制防止信息遭到恶意攻击;我们会部署访问控制机制,确保只有授权人员才可访问个人信息;以及我们会举办安全和隐私保护培训等。 + +总之,我们会尽力保护您的个人信息。尽管如此,任何措施都无法做到无懈可击,也没有任何产品与服务、网站、信息传输、计算机系统、网络连接是绝对安全的。 + +## 6\. 如何访问或控制您的个人信息 + ++ 访问我们持有的您的个人信息并获得副本的权利; ++ 要求我们更新或更正您的个人信息的权利; ++ 要求我们删除您的个人信息的权利; ++ 反对我们对您的个人信息进行处理的权利; ++ 限制我们对您的个人信息进行处理的权利; ++ 向有权的个人信息保护部门提起投诉、举报的权利。 + ++ **位置信息**,指您开启设备定位功能并使用我们基于位置提供的相关服务时,收集的有关您位置的信息,包括: + + 您通过具有定位功能的移动设备使用我们的服务时,通过GPS或WiFi等方式收集的您的地理位置信息; + + 您可以通过关闭定位功能,停止对您的地理位置信息的收集。 ++ **日志信息**,指您使用我们的服务时,系统可能通过cookies、标识符及相关技术收集的信息,包括您的**设备信息**、**浏览信息**、**点击信息**,并将该等信息储存为日志信息,为您提供个性化的用户体验、保障服务安全。您可以通过浏览器设置拒绝或管理cookie、标识符或相关技术的使用。 + +## 2\. 信息的存储 + +**2.1 信息存储的方式和期限** + ++ 我们会通过安全的方式存储您的信息,包括本地存储(例如利用APP进行数据缓存)、数据库和服务器日志。 ++ 一般情况下,我们只会在为实现服务目的所必需的时间内或法律法规规定的条件下存储您的个人信息。 + +**2.2 信息存储的地域** + ++ 我们会按照法律法规规定,将境内收集的用户个人信息存储于中国境内。 ++ 目前我们不会跨境传输或存储您的个人信息。将来如需跨境传输或存储的,我们会向您告知信息出境的目的、接收方、安全保证措施和安全风险,并征得您的同意。 + +**2.3 产品或服务停止运营时的通知** + ++ 当我们的产品或服务发生停止运营的情况时,我们将以推送通知、公告等形式通知您,并在合理期限内删除您的个人信息或进行匿名化处理,法律法规另有规定的除外。 + +## 3\. 信息安全 + +我们使用各种安全技术和程序,以防信息的丢失、不当使用、未经授权阅览或披露。例如,在某些服务中,我们将利用加密技术(例如SSL)来保护您提供的个人信息。但请您理解,由于技术的限制以及可能存在的各种恶意手段,在互联网行业,即便竭尽所能加强安全措施,也不可能始终保证信息百分之百的安全。您需要了解,您接入我们的服务所用的系统和通讯网络,有可能因我们可控范围外的因素而出现问题。 + +## 4\. 我们如何使用信息 + +我们可能将在向您提供服务的过程之中所收集的信息用作下列用途: + ++ 向您提供服务; ++ 在我们提供服务时,用于身份验证、客户服务、安全防范、诈骗监测、存档和备份用途,确保我们向您提供的产品和服务的安全性; ++ 帮助我们设计新服务,改善我们现有服务; ++ 使我们更加了解您如何接入和使用我们的服务,从而针对性地回应您的个性化需求,例如语言设定、位置设定、个性化的帮助服务和指示,或对您和其他用户作出其他方面的回应; ++ 向您提供与您更加相关的广告以替代普遍投放的广告; ++ 评估我们服务中的广告和其他促销及推广活动的效果,并加以改善; ++ 软件认证或管理软件升级; ++ 让您参与有关我们产品和服务的调查。 + +## 5\. 信息共享 + +目前,我们不会主动共享或转让您的个人信息至第三方,如存在其他共享或转让您的个人信息或您需要我们将您的个人信息共享或转让至第三方情形时,我们会直接或确认第三方征得您对上述行为的明示同意。 + +为了投放广告,评估、优化广告投放效果等目的,我们需要向广告主及其代理商等第三方合作伙伴共享您的部分数据,要求其严格遵守我们关于数据隐私保护的措施与要求,包括但不限于根据数据保护协议、承诺书及相关数据处理政策进行处理,避免识别出个人身份,保障隐私安全。 + +我们不会向合作伙伴分享可用于识别您个人身份的信息(例如您的姓名或电子邮件地址),除非您明确授权。 + +我们不会对外公开披露所收集的个人信息,如必须公开披露时,我们会向您告知此次公开披露的目的、披露信息的类型及可能涉及的敏感信息,并征得您的明示同意。 + +随着我们业务的持续发展,我们有可能进行合并、收购、资产转让等交易,我们将告知您相关情形,按照法律法规及不低于本《隐私政策》所要求的标准继续保护或要求新的控制者继续保护您的个人信息。 + +另外,根据相关法律法规及国家标准,以下情形中,我们可能会共享、转让、公开披露个人信息无需事先征得您的授权同意: + ++ 与国家安全、国防安全直接相关的; ++ 与公共安全、公共卫生、重大公共利益直接相关的; ++ 犯罪侦查、起诉、审判和判决执行等直接相关的; ++ 出于维护个人信息主体或其他个人的生命、财产等重大合法权益但又很难得到本人同意的; ++ 个人信息主体自行向社会公众公开个人信息的; ++ 从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。 + +## 6\. 您的权利 + +在您使用我们的服务期间,我们可能会视产品具体情况为您提供相应的操作设置,以便您可以查询、删除、更正或撤回您的相关个人信息,您可参考相应的具体指引进行操作。此外,我们还设置了投诉举报渠道,您的意见将会得到及时的处理。如果您无法通过上述途径和方式行使您的个人信息主体权利,您可以通过本《隐私政策》中提供的联系方式提出您的请求,我们会按照法律法规的规定予以反馈。 + +当您决定不再使用我们的产品或服务时,可以申请注销账户。注销账户后,除法律法规另有规定外,我们将删除或匿名化处理您的个人信息。 + +## 7\. 变更 + +我们可能适时修订本《隐私政策》的条款。当变更发生时,我们会在版本更新时向您提示新的《隐私政策》,并向您说明生效日期。请您仔细阅读变更后的《隐私政策》内容,**若您继续使用我们的服务,即表示您同意我们按照更新后的《隐私政策》处理您的个人信息。** + +## 8\. 未成年人保护 + +我们鼓励父母或监护人指导未满十八岁的未成年人使用我们的服务。我们建议未成年人鼓励他们的父母或监护人阅读本《隐私政策》,并建议未成年人在提交的个人信息之前寻求父母或监护人的同意和指导。 \ No newline at end of file diff --git a/src/conf/version.ts b/src/conf/version.ts new file mode 100755 index 0000000000000000000000000000000000000000..c54a707e20134fa7ed84375cf4e818947d5710ee --- /dev/null +++ b/src/conf/version.ts @@ -0,0 +1,10 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +export const ARGEEMENT_VERSION = '0.0.0'; diff --git a/src/i18n/index.ts b/src/i18n/index.ts new file mode 100755 index 0000000000000000000000000000000000000000..54ffea7140e43ce3185530114286843a7fd089f5 --- /dev/null +++ b/src/i18n/index.ts @@ -0,0 +1,14 @@ +import { createI18n } from 'vue-i18n' +// 语言包 +import CN from './lang/zh-cn' +import EN from './lang/en' + +const i18n = createI18n({ + legacy: false, // 设置为 false,启用 composition API 模式 + locale: sessionStorage.getItem('localeLang') || 'CN', + messages: { + CN, + EN, + }, +}) +export default i18n diff --git a/src/i18n/lang/en.ts b/src/i18n/lang/en.ts new file mode 100755 index 0000000000000000000000000000000000000000..b0f18c1aaffaab8ee6366f08290856dc37aa7000 --- /dev/null +++ b/src/i18n/lang/en.ts @@ -0,0 +1,159 @@ +export default { + home: { + name: 'openEuler Copilot System', + }, + tabs: { + work: 'Work', + private: 'Private', + collect: 'Collect', + like: 'Like', + }, + main: { + describe1:"Hi! I'm", + describe2:", and I'm happy to be of service.", + left_describe:"Feel free to ask me, your AI assistant, about any of these topics, or anything else that's on your mind!~", + os_knowledge:'General OS Knowledge', + os_knowledge_describe:'I can answer your questions about Linux, upstream communities, and toolchains.', + openEuler_expertise:'openEuler Expertise', + openEuler_expertise_describe:'Ask me anything about the openEuler community, technical details, or how to use openEuler.', + beyond_openEuler:'Beyond openEuler', + beyond_openEuler_describe:'I can also provide information about openEuler-compatible hardware, ISVs, and OSVs.', + openEuler_use_cases:'openEuler Use Cases', + openEuler_use_cases_describe:'Discover how openEuler is used in various technical and industry applications.', + command_generation:'Command Generation', + command_generation_describe:'Need help crafting the perfect shell command? I can generate single or complex commands for you.', + smart_shell:'Smart Shell', + smart_shell_describe:'Experience the future of OSs with our smart shell! Use natural language to diagnose and optimize your system.', + try_now:'Try Now', + refresh:"Refresh", + query_interpretation:"Query Interpretation", + Automatic:"Automatic", + ask_me_anything:"Ask me anything about openEuler. Press Shift+Enter to start a new line.", + you_might_want_to_know:"You might want to know:", + close:"Close", + email1:"Email:", + email2:"contact@openeuler.io", + opinions:"AI-generated responses are for reference only and do not reflect the opinions of openEuler.", + service_agreement:"Service Agreement", + privacy_policy:"Privacy Policy", + contact_us:"Contact Us", + version:"Version 1.0.0" + }, + history:{ + new_chat: "New Chat", + latestConversation:"This is the latest conversation", + recent_chats: "Recent Chats", + delete_chats: "Delete Chats", + find_recent_chats: "Find recent chats.", + rename: "Rename", + delete: "Delete", // 注意:这个字段可能与批量删除操作冲突,具体取决于应用逻辑 + delete_successfully: "Delete successfully", + delete_failed: "Delete failed", + cancel: "Cancel", + confirmation_message:"Delete Chats?", + confirmation_message1: "Tip", + select_all: "Select All", + confirmation_content1: "The selected ", + confirmation_content2: " chats will be deleted.", + delete_content1:"This chat", + delete_content2:"will be deleted.", + ok: "OK", + chat_history_limit: "You can view up to 200 of your most recent chats.", + time_filter_today: "Today", + time_filter_last_7_days: "Last 7 days", + time_filter_last_30_days: "Last 30 days", + time_filter_last_6_months: "Last 6 months", + links: "Links", + hiss_basic_software_service_capability_platform: "HiSS Basic Software Service Capability Platform", // 注意:这里我保留了原始的大小写,但通常我们会将首字母大写 + collapse: "Collapse", + no_chat_history: "No chat history available.", // 假设需要一个字段来表示没有历史对话的情况 + expand: "Expand", // 假设界面中有展开历史对话的功能 + }, + feedback:{ + feedbackSuccesful:"Feedback succeeded.", + regenerate: "Regenerate", // 这里我保留了原样,因为通常键名不加双引号 + try_ask_me: "Try ask me:", + eulercopilot_is_thinking: "openEuler Copilot System is thinking…", + generation_stopped: "Generation stopped.", + stop: "Stop", + stopSuccessful: "Stop Successfully", + systemBusy:"The system is busy. Please try again later.", + onlySupport:"I'm sorry, but for now, we only support questions related to the fields of openEuler and Linux.", + copy: "Copy", + copied_successfully: "Copied successfully.", + copied_failed: "Copied failed", + edit_successful:"Edit successful", + edit_failed:"Edit failed", + good_answer: "Good Answer", + bad_answer: "Bad Answer", + your_feedback_helps_us_improve: "Your feedback helps us improve.", + the_information_is_inappropriate_or_illegal: "The information is inappropriate or illegal.", + the_answer_is_not_helpful: "The answer is not helpful.", + i_found_an_error: "I found an error!", + enter_the_link_to_the_correct_answer: "Enter the link to the correct answer.", + describe_the_error: "Describe the error.", + submit: "Submit", + report: "Report", + reason_for_reporting: "Reason for Reporting", + enter_a_description_for_your_report:"Enter a description for your report." + }, + Report:{ + pornographic_content: "Pornographic content", + account_violation: "Account violation", + politically_sensitive_content: "Politically sensitive content", + violence_or_terrorism: "Violence or terrorism", + defamation_or_rumor_spreading: "Defamation or rumor spreading", + insult_to_heroes_or_martyrs: "Insult to heroes or martyrs", + spam: "Spam", + ethnic_or_religious_incitement: "Ethnic or religious incitement", + disturbing_content: "Disturbing content", + abuse_or_harassment: "Abuse or harassment", + gambling_or_fraud: "Gambling or fraud", + consumer_manipulation: "Consumer manipulation", + harm_to_minors: "Harm to minors", + illegal_or_prohibited_items: "Illegal or prohibited items", + other_violations: "Other violations" + }, + Login:{ + login: "Log In", + logout: "Log Out", + login_now: "Log In Now", // 假设这里“立即登录”需要更明确的英文表达 + account: "Account", + enter_account: "Please enter your account", + password: "Password", + enter_password: "Please enter your password", + incorrect_password: "Incorrect password", + api_key_management: "API Key Management", + no_api_key_available: "No API key is available", + create_api_key: "Create API Key", + api_key_display_once: "This API Key will be displayed only once. Please copy and save it securely.", + revoke: "Revoke", // 为了与英文操作保持一致,我将“撤销”明确为对API Key的操作 + refresh: "Refresh", + unauthorized:"Unauthorized page, please login first" + }, + question:{ + open_euler_community_edition_categories: "Community Edition Categories", + lts_release_cycle_and_support: "LTS Release Cycle and Community Support Duration", + innovation_release_cycle_and_support: "Innovation Release Cycle and Community Support Duration", + container_cloud_platform_solution: "Container Cloud Platform Solution (CCPS) of the openEuler Community", + sec_gear_main_functions: "Main Functions of secGear", + dde_description: "What is DDE?", + lustre_description: "What is Lustre?", + open_euler_testing_management_platform: "Testing Management Platform of the openEuler Community", + open_euler_pkgship: "What is pkgship in openEuler?", + open_euler_software_package_introduction_principles: "Introduction Principles of openEuler Software Packages", + download_rpm_without_installing: "How to download an RPM package to the local system without installing it in openEuler?", + count_the_occurrences_of_the_hello:"Generate a shell command to count the occurrences of the 'hello' string in the 'test.txt' file.", + convert_uppercase_to_lowercase: "Give me a shell command to convert uppercase letters to lowercase in text files in the current directory and its subdirectories", + list_files_with_specific_permissions: "Give me a shell command to find and list files with specific permissions in the current directory", + search_error_keyword_with_context: "Give me a shell command to search for the keyword 'error' in text files in the /home directory and its subdirectories, and output the matching lines along with the 3 lines before and after them to a file named 'result.txt'", + clear_dependencies_for_software_package: "How to clear dependencies for software packages in openEuler?", + gpgcheck_purpose_in_dnf: "What is the purpose of the gpgcheck parameter in DNF in openEuler?", + installonly_limit_function_in_dnf: "What is the function of the installonly_limit parameter in DNF in openEuler?", + clean_requirement_on_remove_function_in_dnf: "What is the function of the clean_requirement_on_remove parameter in DNF in openEuler?", + hunan_tobacco_monopoly_applications_on_openeuler: "What are the applications of Hunan Tobacco Monopoly based on openEuler?", + xsky_applications_on_openeuler: "What are the applications of XSKY based on openEuler?" + } + + } + \ No newline at end of file diff --git a/src/i18n/lang/zh-cn.ts b/src/i18n/lang/zh-cn.ts new file mode 100755 index 0000000000000000000000000000000000000000..464b23e3f641272807dd9a73f37ee9c56f4c6bbd --- /dev/null +++ b/src/i18n/lang/zh-cn.ts @@ -0,0 +1,158 @@ +export default { + home: { + name: 'openEuler Copilot System', + }, + tabs: { + work: '作品', + private: '私密', + collect: '收藏', + like: '喜欢', + }, + main: { + describe1: '你好,我是', + describe2: ',很高兴为你服务', + left_describe: '作为你的智能助手,你可以试着问我关于以下方面的内容哦~', + os_knowledge: 'OS领域通用知识问答', + os_knowledge_describe: '包含Linux常规知识、上游信息和工具链介绍及指导', + openEuler_expertise: 'openEuler专业知识', + openEuler_expertise_describe: '包含openEuler社区信息、技术原理和使用指导', + beyond_openEuler: 'openEuler扩展知识', + beyond_openEuler_describe: '包含openEuler周边硬件特性知识和ISV、OSV相关信息', + openEuler_use_cases: 'openEuler应用案例', + openEuler_use_cases_describe: '包含openEuler技术案例、行业应用案例', + command_generation: 'shell命令生成', + command_generation_describe: '帮助用户生成单条命令或复杂命令', + smart_shell: '智能shell', + smart_shell_describe: '欢迎探索首款自然语言交互的智能操作系统:一句话,即享智能诊断与优化', + try_now: '立即体验', + refresh: "换一换", + query_interpretation: "请选择识别方式", + Automatic: "自动识别", + ask_me_anything: "在此输入您想了解的内容,输入Shift+Enter换行", + you_might_want_to_know: "你可能想问", + close: "关闭", + email1: "联系邮箱", + email2: "contact@openeuler.io", + opinions: "所有内容均由人工智能输出,仅供参考,不代表我们的态度和观点", + service_agreement: "服务协议", + privacy_policy: "隐私政策", + contact_us: "联系我们", + version: "版本号0.9.1-内测版" + }, + history: { + new_chat: "新建对话", + latestConversation: "已是最新对话", + recent_chats: "历史记录", + delete_chats: "批量删除", + find_recent_chats: "搜索历史记录", + rename: "重命名", + delete: "删除", + delete_successfully: "删除成功", + delete_failed: "删除失败", + cancel: "取消", + select_all: "全选", + confirmation_message: "提示", + confirmation_message1: "提示", + confirmation_content1: "确定删除已选中的共计", + confirmation_content2: "条对话吗", + delete_content1: "确定删除", + delete_content2: "吗?", + ok: "确定", + chat_history_limit: "仅展示最近200条对话", + time_filter_today: "今天", + time_filter_last_7_days: "最近7天", + time_filter_last_30_days: "最近30天", + time_filter_last_6_months: "最近半年", + links: "友情链接", + hiss_basic_software_service_capability_platform: "基础软件服务能力平台", + collapse: "收起", + no_chat_history: "暂无历史对话", + expand: "展开", + }, + feedback: { + feedbackSuccesful: "反馈成功", + regenerate: "重新生成", + try_ask_me: "你可以继续问我:", + eulercopilot_is_thinking: "openEuler Copilot System正在生成回答...", + generation_stopped: "回答已停止生成", + stop: "停止回答", + stopSuccessful: "暂停成功", + systemBusy: "系统繁忙,请稍后再试", + onlySupport: "很抱歉,暂时只支持问题 openEuler 和 Linux 领域相关的问题", + copy: "复制", + copied_successfully: "复制成功", + copied_failed: "复制失败", + edit_successful: "编辑成功", + edit_failed: "编辑失败", + good_answer: "赞同", + bad_answer: "不赞同", + your_feedback_helps_us_improve: "您的反馈将帮助我们持续进步", + the_information_is_inappropriate_or_illegal: "存在不安全或违法信息", + the_answer_is_not_helpful: "回复内容没什么帮助", + i_found_an_error: "存在错误信息", + enter_the_link_to_the_correct_answer: "请输入参考答案链接", + describe_the_error: "请输入描述", + submit: "提交", + report: "举报", + reason_for_reporting: "选择举报类型", + enter_a_description_for_your_report: "请输入举报描述" + }, + Report: { + pornographic_content: "低俗色情", + account_violation: "账号违规", + politically_sensitive_content: "政治敏感", + violence_or_terrorism: "暴力恐怖", + defamation_or_rumor_spreading: "造谣诽谤", + insult_to_heroes_or_martyrs: "侮辱英烈", + spam: "垃圾广告", + ethnic_or_religious_incitement: "涉民族宗教", + disturbing_content: "引人不适", + abuse_or_harassment: "谩骂攻击", + gambling_or_fraud: "赌博诈骗", + consumer_manipulation: "诱导消费", + harm_to_minors: "危害未成年人", + illegal_or_prohibited_items: "违法违禁品", + other_violations: "其他" + }, + Login: { + login: "登录", + logout: "退出登录", + login_now: "立即登录", + account: "账号", + enter_account: "请输入账号", + password: "密码", + enter_password: "请输入密码", + incorrect_password: "密码输入有误", + api_key_management: "API Key管理", + no_api_key_available: "暂无可用的API Key", + create_api_key: "新建API Key", + api_key_display_once: "此API Key只展示一次,请复制后妥善保存。", + revoke: "撤销", + refresh: "刷新", + unauthorized: "页面未授权,请先登录" + }, + question: { + open_euler_community_edition_categories: "openEuler社区版本有哪些分类?", + lts_release_cycle_and_support: "openEuler长期支持版本的发布间隔周期和社区支持各是多久?", + innovation_release_cycle_and_support: "openEuler社区创新版本的发布间隔周期和社区支持各是多久?", + container_cloud_platform_solution: "openEuler社区的容器云管理平台解决方案(CCPS)是什么?", + sec_gear_main_functions: "secGear主要提供哪三大能力?", + dde_description: "DDE是一款什么组件?", + lustre_description: "Lustre是什么?", + open_euler_testing_management_platform: "openEuler社区的测试管理平台是什么?", + open_euler_pkgship: "openEuler的pkgship是什么?", + open_euler_software_package_introduction_principles: "openEuler软件包引入原则是什么?", + download_rpm_without_installing: "openEuler系统如何将一个RPM包下载到本地而不安装?", + count_the_occurrences_of_the_hello: "请给我一个shell命令,实现以下功能:计算test.txt文件中hello字符串的出现次数", + convert_uppercase_to_lowercase: "给我一个shell命令,实现以下功能:linux命令将本目录及子目录文本文件中的大写字母修改成小写字母", + list_files_with_specific_permissions: "给我一个shell命令,实现以下功能:shell命令查找当前目录下权限符合的文件并列出", + search_error_keyword_with_context: "给我一个shell命令,实现以下功能:在/home目录及其子目录中查找关键字“error”的文本文件,并将匹配行以及它们前后的3行内容输出到名为“result.txt”的文件中", + clear_dependencies_for_software_package: "openEuler系统如何清除软件源的依赖?", + gpgcheck_purpose_in_dnf: "openEuler系统DNF中的gpgcheck参数是用来做什么的?", + installonly_limit_function_in_dnf: "openEuler系统DNF中的installonly_limit参数的作用是?", + clean_requirement_on_remove_function_in_dnf: "openEuler系统DNF中的clean_requirement_on_remove参数具有什么功能?", + hunan_tobacco_monopoly_applications_on_openeuler: "湖南省烟草专卖局基于openeuler系统有哪些应用?", + xsky_applications_on_openeuler: "XSKY星辰天合公司基于openeuler系统有哪些应用?" + } + +} diff --git a/src/main.ts b/src/main.ts new file mode 100755 index 0000000000000000000000000000000000000000..d075df4fb20a6f20f46a432801b6575f1830519f --- /dev/null +++ b/src/main.ts @@ -0,0 +1,69 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { createApp, App as AppInstance } from 'vue'; +import { createPinia } from 'pinia'; +import ElementPlus from 'element-plus'; +import i18n from 'src/i18n'; + +import 'element-plus/dist/index.css'; +import 'highlight.js/styles/github-dark.css'; +import 'src/assets/base.css'; +import 'src/assets/styles/main.scss'; +import 'src/assets/styles/element/index.scss'; +import opendesign2 from '@computing/opendesign2'; +import '@computing/opendesign2/themes/es/css'; +import {qiankunMounted} from './qiankun' + +import App from './App.vue'; +import router from './router'; + +import { + renderWithQiankun, + qiankunWindow, + QiankunProps +} from "vite-plugin-qiankun/dist/helper"; + +let app: AppInstance | null = null + +const render = (props: any = {}) => { + let selector: string = "#app" + if (props && props.container) { + const { container } = props + selector = container && container.querySelector("#app") || "#app" + } + app = createApp(App) + app.use(createPinia()).use(router).use(ElementPlus).use(opendesign2).use(i18n).mount(selector) +} + +const initQianKun = () => { + renderWithQiankun({ + bootstrap() { + }, + mount(props:QiankunProps) { + render(props) + if (props) { + qiankunMounted(props) + } + }, + unmount(props) { + if (app) { + app.unmount() + const appContainer = app._container as HTMLElement + appContainer.innerHTML = "" + app = null + } + }, + update(props) { + } + }) +} + +qiankunWindow.__POWERED_BY_QIANKUN__ ? initQianKun() : render() + diff --git a/src/qiankun.ts b/src/qiankun.ts new file mode 100755 index 0000000000000000000000000000000000000000..e55be34d0985a217c4632701cb393711c18f1b53 --- /dev/null +++ b/src/qiankun.ts @@ -0,0 +1,33 @@ +import { QiankunProps } from "vite-plugin-qiankun/dist/helper"; +import i18n from 'src/i18n'; +import { useAccountStore } from 'src/store'; + +export function qiankunMounted(props: QiankunProps) { + const { theme, lang } = props.inittailData + const language = lang === 'en' ? 'EN' : 'CN' + sessionStorage.setItem('localeLang', language) + sessionStorage.setItem('theme', theme) + i18n.global.locale.value = language + props.onGlobalStateChange((state:any) => { + onQiankunGlobalChange(state) + }) +} + + +function onQiankunGlobalChange(globalState: any) { + if (globalState.logout) { + const { logout } = useAccountStore() + logout() + } + + if (globalState.lang) { + const language = globalState.lang === 'en' ? 'EN' : 'CN' + sessionStorage.setItem('localeLang', language) + i18n.global.locale.value = language + } + + if (globalState.theme) { + sessionStorage.setItem('theme', globalState.theme) + document.body.setAttribute("theme", globalState.theme); + } +} \ No newline at end of file diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100755 index 0000000000000000000000000000000000000000..4db163579a693904a7b3f10026452ad2a53f8626 --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,41 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { createRouter, createWebHistory } from 'vue-router'; +import NotFoundComponent from 'src/views/404.vue'; +import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'; + +const router = createRouter({ + history: createWebHistory(import.meta.env.MODE === 'micro' ? qiankunWindow.__POWERED_BY_QIANKUN__ ? '/eulercopilot/' : '/' : '/'), + routes: [ + { + path: '/', + name: 'dialogue', + component: (): Promise => + import('src/views/dialogue/dialogueView.vue'), + }, + { + path: '/login', + name: 'dialogue-login', + component: (): Promise => + import('src/views/dialogue/dialogueView.vue'), + }, + { + path: '/404', + component: NotFoundComponent, + name: 'NotFound', + }, + { + path: '/:pathMatch(.*)*', + redirect: '/404', + }, + ], +}); + +export default router; diff --git a/src/store/account.ts b/src/store/account.ts new file mode 100755 index 0000000000000000000000000000000000000000..c7b0ca3461ad58d21a6f98f5c8a0a16b35baf2bd --- /dev/null +++ b/src/store/account.ts @@ -0,0 +1,133 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { defineStore } from 'pinia'; +import { reactive } from 'vue'; +import { api } from 'src/apis'; +import { useRouter } from 'vue-router'; +import { LOGOUT_CALLBACK_URL } from 'src/views/dialogue/constants'; +import { successMsg } from 'src/components/Message'; +import i18n from 'src/i18n' +import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'; + +export const useAccountStore = defineStore('account', () => { + const router = useRouter(); + + // 用户信息 + const userinfo = reactive<{ + username: string; + revsionNumber: string | null; + organization: string; + }>({ + username: '', + revsionNumber: null, + organization: '', + }); + + /** + * 登录 + * @param code oidc授权码 + * @returns + */ + const login = async (code: string): Promise => { + const [_, res] = await api.login(code); + if (!_ && res) { + sessionStorage.setItem('csrftk', res.result.csrf_token); + router.push('/'); + return true; + } + return false; + }; + + async function getAuthUrl() { + const [_, res] = await api.queryAuthUrl(); + if (res) { + return res.result + } + return null + } + + /** + * 登录 + * @param user password + * @returns csrftk + */ + const userLogin = async (passwd: string, account: string): Promise => { + const [_, res] = await api.userLogin(passwd, account); + if (!_ && res) { + sessionStorage.setItem('csrftk', res.result.csrf_token); + router.push('/'); + return true; + } + return false; + }; + /** + * 退出登录 + * @returns + */ + const logout = async (): Promise => { + const [_, res] = await api.authorizeLogout(); + if (!_ && res) { + userinfo.username = ''; + userinfo.organization = ''; + userinfo.revsionNumber = null; + sessionStorage.removeItem('csrftk'); + successMsg(i18n.global.t('Login.logout')) + if (!qiankunWindow.__POWERED_BY_QIANKUN__) { + setTimeout(() => { + window.open(LOGOUT_CALLBACK_URL, '_self'); + }, 500) + } + ; + } + }; + /** + * 获取用户信息` + */ + const getUserInfo = async (): Promise => { + const [_, res] = await api.authorizeUser(); + if (!_ && res) { + const { organization, username, revision_number } = res.result; + userinfo.username = username; + userinfo.organization = organization; + userinfo.revsionNumber = revision_number; + return true; + } + return false; + }; + /** + * 刷新token + */ + const refreshAccessToken = async (): Promise => { + const [_, res] = await api.refreshToken(); + if (!_ && res) { + sessionStorage.setItem('csrftk', res.result.csrf_token); + return true; + } + return false; + }; + + const updateAgreement = async (agreementVersion: string): Promise => { + const [, res] = await api.updateRevision(agreementVersion); + if (res) { + userinfo.revsionNumber = res.result.revision_number; + } + }; + + return { + userinfo, + userLogin, + login, + logout, + getUserInfo, + refreshAccessToken, + updateAgreement, + getAuthUrl + }; +}); diff --git a/src/store/conversation.ts b/src/store/conversation.ts new file mode 100755 index 0000000000000000000000000000000000000000..8c0557bdc318bb2fe27762c27a415fcb5e0bd15a --- /dev/null +++ b/src/store/conversation.ts @@ -0,0 +1,544 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { defineStore } from 'pinia'; +import { ref, nextTick } from 'vue'; +import { useAccountStore, useHistorySessionStore } from 'src/store'; +import { + MessageArray, + type ConversationItem, + type RobotConversationItem, + type UserConversationItem, +} from 'src/views/dialogue/types'; +import { api } from 'src/apis'; +import { successMsg } from 'src/components/Message'; +import i18n from 'src/i18n'; + + + +const STREAM_URL = '/api/chat'; +let controller = new AbortController(); +export var txt2imgPath = ref(""); +export var echartsObj = ref({}); +export var echartsHas = ref(false); +var excelPath = ref(''); + +function getCookie(name: string) { + let matches = document.cookie.match(new RegExp( + "(?:^|; )" + name.replace(/([.$?*|{}()\[\]\\/+^])/g, '\\$1') + "=([^;]*)" + )); + return matches ? decodeURIComponent(matches[1]) : undefined; +} + +export const useSessionStore = defineStore('conversation', () => { + // #region ----------------------------------------< scroll >-------------------------------------- + // 会话窗口容器 + const dialogueRef = ref(null); + /** + * 滚动到底部 + */ + const scrollBottom = (action: 'smooth' | 'auto' = 'smooth'): void => { + nextTick(() => { + if (!dialogueRef.value) { + return; + } + //完成所有渲染再执行 + setTimeout(() => { + dialogueRef.value.scrollTo({ + top: dialogueRef.value.scrollHeight, + behavior: action, + }); + }, 0); + }); + }; + + // #endregion + // 是否暂停回答 + const isPaused = ref(false); + // 会话列表 + const conversationList = ref([]); + + // ai回复是否还在生成中 + const isAnswerGenerating = ref(false); + /** + * 请求流式数据 + * @param params + */ + const getStream = async ( + params: { + question: string; + user_selected_plugins?: any, + sessionId?: string; + qaRecordId?: string; + user_selected_flow?: string; + }, + ind?: number + ): Promise => { + const language = sessionStorage.getItem('localeLang') === 'EN' ? 'en' : 'zh'; + const { currentSelectedSession } = useHistorySessionStore(); + params.sessionId = currentSelectedSession; + // 当前问答在整个问答记录中的索引 + const answerIndex = ind ?? conversationList.value.length - 1; + const conversationItem = conversationList.value[answerIndex] as RobotConversationItem; + + controller = new AbortController(); + const headers = { + user: JSON.stringify({ userName: 'openEuler' }), + }; + headers['Content-Type'] = 'application/json; charset=UTF-8'; + headers['X-CSRF-Token'] = getCookie('_csrf_tk'); + try { + let resp; + if (params.user_selected_flow) { + resp = await fetch(STREAM_URL, { + signal: controller.signal, + method: 'POST', + keepalive: true, + headers: headers, + body: JSON.stringify({ + question: params.question, + conversation_id: params.sessionId, + record_id: params.qaRecordId, + files: [], + user_selected_plugins: [], + user_selected_flow: params.user_selected_flow, + language, + }), + }); + } + else if (params.user_selected_plugins) { + resp = await fetch(STREAM_URL, { + signal: controller.signal, + method: 'POST', + keepalive: true, + headers: headers, + body: JSON.stringify({ + question: params.question, + conversation_id: params.sessionId, + record_id: params.qaRecordId, + files: [], + user_selected_plugins: params.user_selected_plugins, + language, + }), + }); + } else { + resp = await fetch(STREAM_URL, { + signal: controller.signal, + keepalive: true, + method: 'POST', + headers: headers, + body: JSON.stringify({ + question: params.question, + conversation_id: params.sessionId, + record_id: params.qaRecordId, + files: [], + user_selected_plugins: [], + language, + }), + }); + } + + const isServiceOk = await handleServiceStatus(resp.status, params, ind); + if (!isServiceOk) { + return; + } + if (!resp.ok) { + throw new Error(`HTTP error! status: ${resp.status}`); + } + if (!resp.body) { + throw new Error(`HTTP error, body not exits`); + } + const reader = resp.body.getReader(); + const decoder = new TextDecoder('utf-8'); + + let isEnd = true; + isPaused.value = false; + excelPath.value = ''; + echartsObj.value = {}; + txt2imgPath.value = ''; + while (isEnd) { + if (isPaused.value) { + // 手动暂停输出 + isAnswerGenerating.value = false; + break; + } + const { done, value } = await reader.read(); + const decodedValue = decoder.decode(value, { stream: true }); + + const isLegal = judgeMessage(answerIndex, decodedValue); + if (!isLegal) { + isEnd = false; + break; + } + + if (done) { + if (excelPath.value.length > 0) { + conversationItem.message[conversationItem.currentInd] += `

下载地址:${excelPath.value}`; + } + + conversationItem.isFinish = true; + isEnd = false; + isAnswerGenerating.value = false; + break; + } + const lines = decodedValue.split('\n\n').filter((line) => line.startsWith('data: {')); + lines.forEach((line) => { + const message = JSON.parse(line.replace(/^data:\s*/, '').trim()); + if (message["POST /txt2img"]) { + const innerObj = JSON.parse(message["POST /txt2img"]); + txt2imgPath.value = 'https://10.2.122.204/images/' + innerObj['image_name']; + } + else if ('gen_graph' in message) { + echartsObj.value = JSON.parse(message["gen_graph"]); + } + else if (message["POST /transcribe"]) { + const innerObj = JSON.parse(message["POST /transcribe"]); + excelPath.value = 'https://10.2.122.203/outputs/' + innerObj['transcription']; + } + else if ('search_suggestions' in message) { + conversationItem.search_suggestions = message.search_suggestions; + } + else if ('files' in message) { + conversationItem.files = message.files; + } + else if ('qa_record_id' in message) { + conversationItem.recordId = message.record_id; + } + else if ('type' in message) { + if(message["type"]=== "render"){ + echartsObj.value = JSON.parse(message["data"]); + echartsHas.value = true; + conversationItem.echartsObj = JSON.parse(message["data"]); + conversationItem.test = true; + }else{ + + } + } else { + // if (message.content.startsWith('<<<') && message.content.endWith('>>>')) { + // const obj = extractAttributesFromMarker(message.content); + // if (obj) { + // conversationItem.message[conversationItem.currentInd] += `## ${obj.title} \n`; + // conversationItem.message[ + // conversationItem.currentInd + // ] += ``; + // } + // } else { + conversationItem.message[conversationItem.currentInd] += message.content; + // } + // if (dialogueRef.value.scrollHeight - (dialogueRef.value.clientHeight + dialogueRef.value.scrollTop) >= 2) { + // return + // } else { + // scrollBottom(); + // } + scrollBottom(); + } + }); + } + } catch (err: any) { + console.log(err); + isPaused.value = true; + isAnswerGenerating.value = false; + (conversationList.value[answerIndex] as RobotConversationItem).isFinish = true; + if (err.name === 'AbortError') { + successMsg(i18n.global.t('feedback.stopSuccessful')); + (conversationList.value[answerIndex] as RobotConversationItem).isFinish = true; + } else { + (conversationList.value[answerIndex] as RobotConversationItem).message[ + (conversationList.value[answerIndex] as RobotConversationItem).currentInd + ] += i18n.global.t('feedback.systemBusy'); + } + } + }; + + /** + * 解析图表格式的文本 + */ + const extractAttributesFromMarker = (str: string): { title: string; link: string } | null => { + const regex = /<<<[^>]*title="([^"]+)"[^>]*link="([^"]+)"[^>]*>>>/; + + const match = str.match(regex); + + if (match) { + return { + title: match[1], + link: match[2], + }; + } else { + return null; + } + }; + + const handleServiceStatus = async ( + status: number, + params: { + question: string; + sessionId?: string; + qaRecordId?: string; + }, + ind?: number + ): Promise => { + if (status === 401 || status === 403) { + // 鉴权失败重发 + const store = useAccountStore(); + const res = await store.refreshAccessToken(); + if (res) { + await getStream(params, ind); + } + return false; + } else if (status === 429) { + throw new Error(`HTTP error, Rate limit exceeded`); + } else { + return true; + } + }; + /** + * 处理不合法信息 + * @param ind 当前问答对索引 + */ + const judgeMessage = (ind: number, msg: string): boolean => { + let errorMsg = ''; + if (msg.includes('[SENSITIVE]')) { + errorMsg = i18n.global.t('feedback.onlySupport'); + } + //error没加限制 + if (msg.includes('[ERROR]')) { + errorMsg = i18n.global.t('feedback.systemBusy'); + } + if (errorMsg) { + (conversationList.value[ind] as RobotConversationItem).message[ + (conversationList.value[ind] as RobotConversationItem).currentInd + ] = errorMsg; + (conversationList.value[ind] as RobotConversationItem).isFinish = true; + isAnswerGenerating.value = false; + scrollBottom(); + return false; + } + + return true; + }; + /** + * 发送问题 + * @param question 问题 + * @param regenerateInd 重新生成的回答索引 + */ + const sendQuestion = async ( + question: string, + user_selected_plugins?: string[], + regenerateInd?: number, + qaRecordId?: string, + user_selected_flow?: string, + ): Promise => { + const { updateSessionTitle, currentSelectedSession } = useHistorySessionStore(); + if (conversationList.value.length === 0) { + // 如果当前还没有对话记录,将第一个问题的questtion作为对话标题 + updateSessionTitle({ sessionId: currentSelectedSession, title: question.slice(0, 20) }); + } + if (regenerateInd) { + // 重新生成,指定某个回答,修改默认索引 + (conversationList.value[regenerateInd] as RobotConversationItem).message.push('');//123 + (conversationList.value[regenerateInd] as RobotConversationItem).currentInd = + (conversationList.value[regenerateInd] as RobotConversationItem).message.length - 1;//123 + } else { + // 初次生成 ,创建一个问题和一个回答 + const ind = conversationList.value.length - 1; + const a = new MessageArray() + a.addItem('', '', 2); + conversationList.value.push( + { + cid: ind + 1, + belong: 'user', + message: question, + }, + { + cid: ind + 2, + belong: 'robot', + message: [''], + messageList: a, + currentInd: 0, + isFinish: false, + recordId: '', + groupId: '', + sessionId: '', + } + ); + } + isAnswerGenerating.value = true; + scrollBottom(); + if (user_selected_flow) { + await getStream( + { + question, + qaRecordId, + user_selected_plugins, + user_selected_flow, + }, + regenerateInd ?? undefined + ) + } else if (user_selected_plugins?.length) { + await getStream( + { + question, + qaRecordId, + user_selected_plugins: [...user_selected_plugins], + }, + regenerateInd ?? undefined + ) + } else { + await getStream( + { + question, + qaRecordId, + }, + regenerateInd ?? undefined + ); + } + }; + /** + * 暂停流式返回 + */ + const pausedStream = async (cid?: number): Promise => { + const answerIndex = conversationList.value.findIndex((val) => val.cid === cid) !== -1 ? conversationList.value.findIndex((val) => val.cid === cid) : conversationList.value.length - 1; + isPaused.value = true; + (conversationList.value[answerIndex] as RobotConversationItem).isFinish = true; + cancel(); + await api.stopGeneration(); + }; + /** + * 重新生成回答 + * @param cid + */ + const reGenerateAnswer = (cid: number, user_selected_plugins: any[]): void => { + const answerInd = conversationList.value.findIndex((val) => val.cid === cid); + const question = (conversationList.value[answerInd - 1] as UserConversationItem).message; + const recordId = (conversationList.value[answerInd] as RobotConversationItem).recordId; + (conversationList.value[answerInd] as RobotConversationItem).isFinish = false; + if (!question) { + return; + } + sendQuestion(question, user_selected_plugins, answerInd, recordId); + }; + + // #region ----------------------------------------< pagenation >-------------------------------------- + /** + * 上一条 + * @param cid + */ + const prePage = (cid: number): void => { + const answerInd = conversationList.value.findIndex((val) => val.cid === cid); + if ((conversationList.value[answerInd] as RobotConversationItem).currentInd === 0) { + return; + } + (conversationList.value[answerInd] as RobotConversationItem).currentInd -= 1; + const index = (conversationList.value[answerInd] as RobotConversationItem).currentInd; + }; + /** + * 下一条 + * @param cid + */ + const nextPage = (cid: number): void => { + const answerInd = conversationList.value.findIndex((val) => val.cid === cid); + + if ( + conversationList.value[answerInd].message.length - 1 === + (conversationList.value[answerInd] as RobotConversationItem).currentInd + ) { + return; + } + (conversationList.value[answerInd] as RobotConversationItem).currentInd += 1; + const index = (conversationList.value[answerInd] as RobotConversationItem).currentInd; + + }; + // #endregion + + /** + * 获取历史对话数据 + * @param sessionId + */ + const getConversation = async (sessionId: string): Promise => { + const [_, res] = await api.getHistoryConversation(sessionId); + // + if (!_ && res) { + conversationList.value = []; + res.result.forEach((record) => { + if ( + (conversationList.value as RobotConversationItem[]).find( + (i) => i.groupId === record.group_id + ) + ) { + const re = (conversationList.value as RobotConversationItem[]).find( + (i) => i.groupId === record.group_id + ); + re?.message.push(record.answer); + if (typeof (re?.message) !== 'string') { + re?.messageList.addItem(record.answer, record.record_id, typeof (record.is_like) === 'object' ? 2 : Number(record.is_like)); + } + return; + } + const a = new MessageArray(); + a.addItem(record.answer, record.record_id, typeof (record.is_like) === 'object' ? 2 : Number(record.is_like)); + conversationList.value.push( + { + cid: conversationList.value.length + 1, + belong: 'user', + message: record.question, + createdAt: record.created_time, + }, + { + cid: conversationList.value.length + 2, + belong: 'robot', + message: [record.answer], + messageList: a, + currentInd: 0, + isAgainst: false, + isSupport: false, + isFinish: true, + recordId: record.record_id, + sessionId: record.conversation_id, + groupId: record.group_id, + } + ); + scrollBottom('auto'); + }); + } + }; + + const comment = (cid: number, isSupport: boolean, index: number): void => { + const ind = conversationList.value.find((item) => item.cid === cid); + // ind.message.items[index].is_like = isSupport; + }; + + const cancel = () => { + controller.abort(); + }; + return { + isPaused, + conversationList, + isAnswerGenerating, + dialogueRef, + sendQuestion, + pausedStream, + prePage, + nextPage, + reGenerateAnswer, + getConversation, + comment, + cancel, + }; +}); + +export const useChangeThemeStore = defineStore('theme', () => { + const theme = ref(''); + if (sessionStorage.getItem('theme')) { + theme.value = sessionStorage.getItem('theme') || 'dark'; + } + return { + theme, + } +}); + diff --git a/src/store/historySession.ts b/src/store/historySession.ts new file mode 100755 index 0000000000000000000000000000000000000000..b7c47e18e222f915976e36dd0f4312e831740981 --- /dev/null +++ b/src/store/historySession.ts @@ -0,0 +1,194 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { api } from 'src/apis'; +import { defineStore } from 'pinia'; +import { ref, computed } from 'vue'; +import { storeToRefs } from 'pinia'; +import { useSessionStore } from '.'; +import type { SessionItem } from 'src/components/sessionCard/type'; +import { successMsg } from 'src/components/Message'; +import i18n from 'src/i18n'; +export interface HistorySessionItem { + sessionId: string; + title: string; + createdTime: string | Date; +} + +export const useHistorySessionStore = defineStore('sessionStore', () => { + // 历史会话列表 + const historySession = ref([]); + const user_selected_plugins = ref([]); + const selectMode = ref([]) + const currentSelectedSession = ref(''); + /** + * 选择历史会话 + * @param conversation_id 会话id + */ + const changeSession = async (sessionId: string): Promise => { + const { isAnswerGenerating } = useSessionStore(); + if (currentSelectedSession.value === sessionId || isAnswerGenerating) { + return; + } + currentSelectedSession.value = sessionId; + const { getConversation } = useSessionStore(); + await getConversation(currentSelectedSession.value).then(()=> { + const a = document.getElementsByClassName('draw'); + for(let i of a){ + i.style.display = 'none' ; + } + }); + }; + // #region -----------------------------------------< select conversation >------------------------------------------------ + // 被选中的会话id列表 + const selectedSessionIds = ref([]); + + // 是否全选 + const isSelectedAll = ref(false); + // 不确定状态 + const indeterminate = computed(() => + selectedSessionIds.value.length === 0 + ? false + : selectedSessionIds.value.length !== historySession.value.length + ); + /** + * 全选 + */ + const selectAllSession = (): void => { + isSelectedAll.value + ? (selectedSessionIds.value = historySession.value.map((item) => item.sessionId)) + : (selectedSessionIds.value = []); + }; + /** + * 选中某个会话 + * @param sessionId 会话id + */ + const selectSession = (sessionId: string): void => { + selectedSessionIds.value.includes(sessionId) + ? (selectedSessionIds.value = selectedSessionIds.value.filter((val) => val !== sessionId)) + : selectedSessionIds.value.push(sessionId); + // 更新isSelectedAll的值 + if (selectedSessionIds.value.length === historySession.value.length) { + isSelectedAll.value = true; + } else { + isSelectedAll.value = false; + } + }; + // #endregion + + /** + * 清空选择会话列表 + * @param conversation_id 会话id + */ + const initSessionList = (): void => { + selectedSessionIds.value = []; + }; + /** + * 获取历史会话列表 + * @returns + */ + const getHistorySession = async (): Promise => { + const [_, res] = await api.getSessionRecord(); + const { conversationList } = storeToRefs(useSessionStore()); + if (!_ && res) { + historySession.value = res.result.reverse().map((item) => ({ + sessionId: item.conversation_id, + createdTime: item.created_time, + title: item.title, + })); + if(res.result.length === 0){ + await generateSession(); + } + if (!currentSelectedSession.value) { + currentSelectedSession.value = res.result[0]?.conversation_id; + } + if (currentSelectedSession.value) { + const { getConversation, isAnswerGenerating } = useSessionStore(); + if (isAnswerGenerating) { + return; + } + await getConversation(currentSelectedSession.value); + return; + } + await createNewSession(); + if (res.result.length === 0) { + conversationList.value = []; + } + } + }; + /** + * 更新会话标题 + * @param conversation + * @returns + */ + const updateSessionTitle = async (conversation: SessionItem): Promise => { + const [_] = await api.updateSession( + { + sessionId: conversation.sessionId, + }, + { + title: conversation.title, + } + ); + if (_) { + return false; + } + await getHistorySession(); + return true; + }; + + /** + * 创建新会话 + */ + const createNewSession = async (): Promise => { + const sId = historySession.value.length === 0 ? null : historySession.value[0]?.sessionId; + if (sId) { + const [, cov] = await api.getHistoryConversation(sId); + if (cov && cov.result.length === 0) { + if (currentSelectedSession.value !== sId) { + currentSelectedSession.value = sId; + } + successMsg(i18n.global.t('history.latestConversation')); + await getHistorySession(); + } else { + await generateSession(); + } + } else { + await generateSession(); + } + }; + /** + * 创建一个新的会话 + */ + const generateSession = async (): Promise => { + const [_, res] = await api.createSession(); + if (!_ && res) { + currentSelectedSession.value = res.result.conversation_id; + await getHistorySession(); + } + }; + + return { + historySession, + currentSelectedSession, + selectedSessionIds, + indeterminate, + isSelectedAll, + changeSession, + selectAllSession, + selectSession, + getHistorySession, + updateSessionTitle, + createNewSession, + initSessionList, + generateSession, + user_selected_plugins, + selectMode, + }; +}); diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100755 index 0000000000000000000000000000000000000000..11b874750ec38d976bba80f371a558c42f0db14e --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,14 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +export * from './account'; +export * from './conversation'; +export * from './historySession'; +export * from './lang'; + diff --git a/src/store/lang.ts b/src/store/lang.ts new file mode 100755 index 0000000000000000000000000000000000000000..dd39f679885a2af5e37e7e44d95fdefb43a52c2b --- /dev/null +++ b/src/store/lang.ts @@ -0,0 +1,17 @@ +import { defineStore } from 'pinia' +import { ref } from 'vue' +import { useI18n } from 'vue-i18n' + +export const useLangStore = defineStore('lang', () => { + const i18n = useI18n() + const language = ref(sessionStorage.getItem('localeLang') || 'CN'); + const changeLanguage = (data: 'CN' | 'EN') => { + language.value = data.toString(); + i18n.locale.value = language.value; + sessionStorage.setItem('localeLang', data); + } + return { + language, + changeLanguage + } +}) diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100755 index 0000000000000000000000000000000000000000..8cd5918b022b53eaeb43314cb521c68576f0985a --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,11 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +export * from './markedjs'; +export * from './tools'; diff --git a/src/utils/marked.js b/src/utils/marked.js new file mode 100755 index 0000000000000000000000000000000000000000..b51736b396e6dc2f4bdfeff373bd57bc8d32e247 --- /dev/null +++ b/src/utils/marked.js @@ -0,0 +1,68 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { marked } from 'marked'; +import hljs from 'highlight.js'; +import { randomInt } from './tools'; + +marked.setOptions({ + gfm: true, // 启动类似于Github样式的Markdown语法 + breaks: false, // 支持Github换行符,必须打开gfm选项 + sanitize: false, // 原始输出,忽略HTML标签(关闭后,可直接渲染HTML标签) + pedantic: false, // 只解析符合Markdwon定义的,不修正Markdown的错误 +}); + +export const link = /\bhttps?:\/\/[\w/.-]+(?`; + +/** + * 自定义代码块内容解析 + * @param code 解析后的HTML代码 + * @param language 语言 + * @returns + */ +export const renderCode = (code, language) => { + const id = `pre-${Date.now()}-${randomInt()}`; + const lang = language ? language : 'bash'; + return `

${lang}${ICON_SVG}
${ + hljs.highlight(code, { language: lang }).value + }
`; +}; + +/** + * 解析网页链接内容 + * @param href + * @param text + * @returns + */ +export const renderLink = (href, text) => { + if (href === text) { + const txt = text.replace(link, ''); + const url = (href.match(link) ?? [])[0]; + return `${url}${txt}`; + } + return `${text}`; +}; + +/** + * 自定义渲染 + */ +const renderer = { + code(code, infostring) { + return renderCode(code, infostring); + }, + link(href, title, text) { + return renderLink(href, text); + }, +}; + +marked.use({ renderer }); + +export default marked; diff --git a/src/utils/markedjs.ts b/src/utils/markedjs.ts new file mode 100755 index 0000000000000000000000000000000000000000..ff876d370617fb08cbb4e6017db50398cd1dacd8 --- /dev/null +++ b/src/utils/markedjs.ts @@ -0,0 +1,78 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import hljs from 'highlight.js'; +import { marked } from 'marked'; + +import { randomInt } from './tools'; + +/** + * 保存按钮 + */ +const ICON_SVG = ``; + +export const doubleDollar = /(?<=\$\$).*?(?=\$\$)/; +export const doubleWell = /(?<=##).*?(?=##)/; +export const link = /\bhttps?:\/\/[\w/.-]+(?-------------------------------------- +/** + * markedjs 配置 + */ +marked.setOptions({ + gfm: true, // 启动类似于Github样式的Markdown语法 + breaks: false, // 支持Github换行符,必须打开gfm选项 + pedantic: false, // 只解析符合Markdwon定义的,不修正Markdown的错误 + // 高亮的语法规范 + highlight: (code: string, lang: string) => hljs.highlight(code, { language: lang }).value, +}); + +// #endregion + +// #region ----------------------------------------< renderer >-------------------------------------- +/** + * 自定义代码块内容解析 + * @param code 解析后的HTML代码 + * @param language 语言 + * @returns + */ +export const renderCode = (code: string, language: string | undefined): string => { + const id = `pre-${Date.now()}-${randomInt()}`; + return `
${language}${ICON_SVG}
${code}
`; +}; + +/** + * 解析网页链接内容 + * @param href + * @param text + * @returns + */ +export const renderLink = (href: string, text: string): string => { + if (href === text) { + const txt = text.replace(link, ''); + const url = (href.match(link) ?? [])[0]; + return `${url}${txt}`; + } + return `${text}`; +}; + +/** + * 自定义渲染 + */ +const renderer = { + code(code: string, infostring: string | undefined): string { + return renderCode(code, infostring); + }, + link(href: string, title: string | null | undefined, text: string): string { + return renderLink(href, text); + }, +}; + +marked.use({ renderer }); +// #endregion +export default marked; diff --git a/src/utils/tools.ts b/src/utils/tools.ts new file mode 100755 index 0000000000000000000000000000000000000000..8cd637501f212a1808755ffdf4bd51f292189b99 --- /dev/null +++ b/src/utils/tools.ts @@ -0,0 +1,76 @@ +// Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. +// licensed under the Mulan PSL v2. +// You can use this software according to the terms and conditions of the Mulan PSL v2. +// You may obtain a copy of Mulan PSL v2 at: +// http://license.coscl.org.cn/MulanPSL2 +// THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +// PURPOSE. +// See the Mulan PSL v2 for more details. +import { successMsg } from 'src/components/Message'; +import i18n from 'src/i18n'; + +/** + * 随机整数范围 min <= return < max + * @param min + * @param max + * @returns + */ +export const randomInt = (): number => { + return window.crypto.getRandomValues(new Uint32Array(1))[0]; +}; + +type HtmlEvent = 'copyPreCode'; +/** + * HTML事件分发 + * @param _t dom节点 + * @param _ty event 类型 + * @param event 事件 e + * @param type 自定义类型type + * @param data 自定义属性 + */ +export const onHtmlEventDispatch = ( + _t: any, + _ty: any, + event: any, + type: HtmlEvent, + data: any, +): void => { + if (type === 'copyPreCode') { + const code = document.getElementById(data); + if (code) { + writeText(code.innerText); + } + successMsg(i18n.global.t('feedback.copied_successfully')) + } +}; + +/** + * 复制code + * @param text code内容 + */ +export const writeText = (text: string): void => { + if (navigator.clipboard && window.isSecureContext) { + const type = 'text/plain'; + const blob = new Blob([text], { type }); + const data = [new ClipboardItem({ [type]: blob })]; + navigator.clipboard.write(data).then( + () => {}, + () => {}, + ); + } else { + const textArea = document.createElement('textarea'); + textArea.value = text; + textArea.style.position = 'absolute'; + textArea.style.opacity = '0'; + textArea.style.left = '-999999px'; + textArea.style.top = '-999999px'; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + new Promise((res, rej) => { + document.execCommand('copy') ? res() : rej(new Error('复制失败')); + textArea.remove(); + }); + } +}; diff --git a/src/views/404.vue b/src/views/404.vue new file mode 100755 index 0000000000000000000000000000000000000000..afeadcd7d8aba0c75f7743570610d0c6999b40ca --- /dev/null +++ b/src/views/404.vue @@ -0,0 +1,27 @@ + + + diff --git a/src/views/dialogue/Copilot.vue b/src/views/dialogue/Copilot.vue new file mode 100755 index 0000000000000000000000000000000000000000..b787f19f62f7a419a30159f70e787e57342968ee --- /dev/null +++ b/src/views/dialogue/Copilot.vue @@ -0,0 +1,155 @@ + + + diff --git a/src/views/dialogue/components/AgainstPopover.vue b/src/views/dialogue/components/AgainstPopover.vue new file mode 100755 index 0000000000000000000000000000000000000000..7f0903651df8873de16578e55990601188698392 --- /dev/null +++ b/src/views/dialogue/components/AgainstPopover.vue @@ -0,0 +1,275 @@ + + +