Commit adba6c80 authored by jiangwei's avatar jiangwei

first commit

parents
Pipeline #286 failed with stages
> 1%
last 2 versions
not dead
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
# DeepSeek API Configuration
VITE_DEEPSEEK_API_KEY=sk-ceb23bc709b641b79bea590bc3f7e965
VITE_API_BASE_URL=/api
VITE_MODEL_NAME=deepseek-chat
VITE_API_HOST=https://api.deepseek.com
\ No newline at end of file
module.exports = {
root: true,
env: {
node: true
},
extends: [
'plugin:vue/essential',
'@vue/standard'
],
parserOptions: {
parser: 'babel-eslint'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}
node_modules
.DS_Store
.github
dist
.npmrc
.cache
tests/server/static
tests/server/static/upload
.local
# local env files
.env.local
.env.*.local
.eslintcache
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.svn
# .vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
/os_del.cmd
os_del.cmd
/.vscode/
/.history/
/svn clear.bat
# DeepSeek Web Chat
一个基于 Vue 3 开发的 Web 聊天界面,用于调用 DeepSeek API 实现 AI 对话功能。
![image](https://github.com/user-attachments/assets/66041177-c7ce-433c-a3f5-fb45f6454f65)
## 背景说明
由于 DeepSeek 官网经常面临访问压力大的问题,但模型已开源,许多大厂都部署了该模型的服务。本项目采用腾讯云部署的 DeepSeek 模型实现。
> 🔗 API 文档:[腾讯云 DeepSeek API 文档](https://cloud.tencent.com/document/product/1772/115969)
> 🎯 主要优势:服务稳定,响应快速,支持流式输出
>
> PS: 腾讯提供的DeepSeek接口为671b模型,API免费到2025年2月25日23:59:59
## 功能特点
- 💬 实时对话功能
- 🤔 显示 AI 思考过程
- 🔄 支持新对话
- 📱 响应式设计
- 🌈 优雅的动画效果
## 快速开始
##### 1.克隆项目
```bash
git clone https://github.com/momoxiaoshuai/deepseek-chat.git
cd deepseek-web-chat
```
##### 2.安装依赖
```bash
npm install
```
##### 3.配置环境变量
1. 复制环境变量示例文件:
```bash
cp .env.example .env
```
2. 编辑 `.env` 文件,设置你的 API 密钥:
```bash
VITE_DEEPSEEK_API_KEY=your-api-key-here
VITE_API_BASE_URL=/api
```
> ⚠️ 注意:不要将包含实际 API 密钥的 `.env` 文件提交到版本控制系统中
##### 4.本地开发
```bash
npm run dev
```
##### 5.构建部署
```bash
npm run build
```
## 部署说明
### Nginx 配置示例
```
nginx
server {
listen 80;
server_name your-domain.com; # 替换成你的域名或 IP
root /path/to/your/dist; # 替换成你的 dist 目录路径
index index.html;
# 处理前端路由
location / {
try_files $uri $uri/ /index.html last;
}
# API 代理配置
location /api/ {
proxy_pass https://api.lkeap.cloud.tencent.com/v1/;
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2;
proxy_set_header Host api.lkeap.cloud.tencent.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;
# 关闭缓冲,确保流式响应正常工作
proxy_buffering off;
}
error_log /var/log/nginx/deepseek_error.log;
access_log /var/log/nginx/deepseek_access.log;
}
```
### 部署步骤
1. 构建项目
```bash
npm run build
```
2. 将 dist 目录上传到服务器
```bash
scp -r dist/ user@your-server:/path/to/your/dist
```
3. 配置 Nginx
- 将上述 Nginx 配置保存到 `/etc/nginx/conf.d/deepseek.conf`
- 检查配置是否正确:`sudo nginx -t`
- 重启 Nginx:`sudo systemctl restart nginx`
## 环境要求
- Node.js >= 16
- npm >= 7
- 现代浏览器(支持 ES6+)
## 技术栈
- Vue 3
- Vite
- Nginx
## 注意事项
- API 密钥存储在 `.env` 文件中,确保该文件不会被提交到代码仓库
- 在生产环境中,建议使用环境变量或密钥管理服务来存储 API 密钥
- 生产环境建议使用 HTTPS
- 定期检查并更新依赖包
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>DeepSeek</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Fira+Code&display=swap" rel="stylesheet">
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
width: 100vw;
height: 100vh;
max-width: 100vw;
max-height: 100vh;
}
</style>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
\ No newline at end of file
// 简单的依赖安装脚本
import fs from 'fs';
import path from 'path';
// 读取package.json
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
console.log('检查依赖...');
// 检查关键依赖是否存在
const requiredDeps = [
'@vitejs/plugin-vue',
'vue',
'vue-router',
'vuex'
];
let missingDeps = [];
requiredDeps.forEach(dep => {
const depPath = path.join('node_modules', dep);
if (!fs.existsSync(depPath)) {
missingDeps.push(dep);
}
});
if (missingDeps.length > 0) {
console.log('缺失的依赖:', missingDeps);
console.log('请手动安装这些依赖');
} else {
console.log('所有关键依赖都已安装');
}
// 创建简单的vite配置备用
const viteConfigBackup = `
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
server: {
port: 5174
}
})
`;
fs.writeFileSync('vite.config.backup.js', viteConfigBackup);
console.log('创建了备用vite配置文件');
\ No newline at end of file
{
"name": "deepseek-chat",
"version": "0.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "deepseek-chat",
"version": "0.0.0",
"dependencies": {
"3d-force-graph": "^1.67.6",
"core-js": "^3.6.5",
"d3": "^6.2.0",
"d3-context-menu": "^1.1.2",
"marked": "^12.0.0",
"openai": "^4.28.0",
"three-spritetext": "^1.5.3",
"uuid": "^11.1.0",
"vue": "^3.3.0",
"vue-router": "^4.0.0",
"vuex": "^4.0.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^4.0.0",
"vite": "^5.0.0"
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.28.5",
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.28.5",
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.5.tgz",
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
"license": "MIT",
"dependencies": {
"@babel/types": "^7.28.5"
},
"bin": {
"parser": "bin/babel-parser.js"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@babel/runtime": {
"version": "7.28.4",
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.28.4.tgz",
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/types": {
"version": "7.28.5",
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.5.tgz",
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
"integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
"integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
"integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
"integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
"integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
"integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
"integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
"integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
"integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
"integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
"integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
"integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
"integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
"integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
"integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
"integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
"integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
"integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
"integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
"integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
"integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
"integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
"integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=12"
}
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
"@jridgewell/trace-mapping": "^0.3.24"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.11",
"resolved": "https://registry.npmmirror.com/@jridgewell/source-map/-/source-map-0.3.11.tgz",
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.5",
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.31",
"resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@parcel/watcher": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.1.tgz",
"integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"detect-libc": "^1.0.3",
"is-glob": "^4.0.3",
"micromatch": "^4.0.5",
"node-addon-api": "^7.0.0"
},
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"@parcel/watcher-android-arm64": "2.5.1",
"@parcel/watcher-darwin-arm64": "2.5.1",
"@parcel/watcher-darwin-x64": "2.5.1",
"@parcel/watcher-freebsd-x64": "2.5.1",
"@parcel/watcher-linux-arm-glibc": "2.5.1",
"@parcel/watcher-linux-arm-musl": "2.5.1",
"@parcel/watcher-linux-arm64-glibc": "2.5.1",
"@parcel/watcher-linux-arm64-musl": "2.5.1",
"@parcel/watcher-linux-x64-glibc": "2.5.1",
"@parcel/watcher-linux-x64-musl": "2.5.1",
"@parcel/watcher-win32-arm64": "2.5.1",
"@parcel/watcher-win32-ia32": "2.5.1",
"@parcel/watcher-win32-x64": "2.5.1"
}
},
"node_modules/@parcel/watcher-android-arm64": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz",
"integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-arm64": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz",
"integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-x64": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz",
"integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-freebsd-x64": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz",
"integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-glibc": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz",
"integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-musl": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz",
"integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-glibc": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz",
"integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-musl": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz",
"integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-glibc": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz",
"integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-musl": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz",
"integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-arm64": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz",
"integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-ia32": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz",
"integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-x64": {
"version": "2.5.1",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz",
"integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"peer": true,
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher/node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@parcel/watcher/node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/@parcel/watcher/node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/@parcel/watcher/node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
},
"engines": {
"node": ">=8.6"
}
},
"node_modules/@parcel/watcher/node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.6.tgz",
"integrity": "sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-android-arm64": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.6.tgz",
"integrity": "sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.6.tgz",
"integrity": "sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-darwin-x64": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.6.tgz",
"integrity": "sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
]
},
"node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.6.tgz",
"integrity": "sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.6.tgz",
"integrity": "sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.6.tgz",
"integrity": "sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.6.tgz",
"integrity": "sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==",
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.6.tgz",
"integrity": "sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.6.tgz",
"integrity": "sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.6.tgz",
"integrity": "sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==",
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.6.tgz",
"integrity": "sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==",
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.6.tgz",
"integrity": "sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==",
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.6.tgz",
"integrity": "sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==",
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.6.tgz",
"integrity": "sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.6.tgz",
"integrity": "sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.6.tgz",
"integrity": "sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.6.tgz",
"integrity": "sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==",
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.6.tgz",
"integrity": "sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==",
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
]
},
"node_modules/@tweenjs/tween.js": {
"version": "25.0.0",
"resolved": "https://registry.npmmirror.com/@tweenjs/tween.js/-/tween.js-25.0.0.tgz",
"integrity": "sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==",
"license": "MIT"
},
"node_modules/@types/estree": {
"version": "1.0.6",
"resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz",
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true
},
"node_modules/@types/node": {
"version": "18.19.75",
"resolved": "https://registry.npmmirror.com/@types/node/-/node-18.19.75.tgz",
"integrity": "sha512-UIksWtThob6ZVSyxcOqCLOUNg/dyO1Qvx4McgeuhrEtHTLFTf7BBhEazaE4K806FGTPtzd/2sE90qn4fVr7cyw==",
"dependencies": {
"undici-types": "~5.26.4"
}
},
"node_modules/@types/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmmirror.com/@types/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==",
"dependencies": {
"@types/node": "*",
"form-data": "^4.0.0"
}
},
"node_modules/@vitejs/plugin-vue": {
"version": "4.6.2",
"resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-4.6.2.tgz",
"integrity": "sha512-kqf7SGFoG+80aZG6Pf+gsZIVvGSCKE98JbiWqcCV9cThtg91Jav0yvYFC9Zb+jKetNGF6ZKeoaxgZfND21fWKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^14.18.0 || >=16.0.0"
},
"peerDependencies": {
"vite": "^4.0.0 || ^5.0.0",
"vue": "^3.2.25"
}
},
"node_modules/@vue/compiler-core": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.22.tgz",
"integrity": "sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.4",
"@vue/shared": "3.5.22",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-dom": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz",
"integrity": "sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==",
"license": "MIT",
"dependencies": {
"@vue/compiler-core": "3.5.22",
"@vue/shared": "3.5.22"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz",
"integrity": "sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==",
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.4",
"@vue/compiler-core": "3.5.22",
"@vue/compiler-dom": "3.5.22",
"@vue/compiler-ssr": "3.5.22",
"@vue/shared": "3.5.22",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.19",
"postcss": "^8.5.6",
"source-map-js": "^1.2.1"
}
},
"node_modules/@vue/compiler-ssr": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz",
"integrity": "sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.22",
"@vue/shared": "3.5.22"
}
},
"node_modules/@vue/devtools-api": {
"version": "6.6.4",
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
"license": "MIT"
},
"node_modules/@vue/reactivity": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.22.tgz",
"integrity": "sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==",
"license": "MIT",
"dependencies": {
"@vue/shared": "3.5.22"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.22.tgz",
"integrity": "sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.22",
"@vue/shared": "3.5.22"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz",
"integrity": "sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==",
"license": "MIT",
"dependencies": {
"@vue/reactivity": "3.5.22",
"@vue/runtime-core": "3.5.22",
"@vue/shared": "3.5.22",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.22.tgz",
"integrity": "sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==",
"license": "MIT",
"dependencies": {
"@vue/compiler-ssr": "3.5.22",
"@vue/shared": "3.5.22"
},
"peerDependencies": {
"vue": "3.5.22"
}
},
"node_modules/@vue/shared": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.22.tgz",
"integrity": "sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==",
"license": "MIT"
},
"node_modules/3d-force-graph": {
"version": "1.79.0",
"resolved": "https://registry.npmmirror.com/3d-force-graph/-/3d-force-graph-1.79.0.tgz",
"integrity": "sha512-0RUNcfiH12f93loY/iS4wShzhXzdLLN4futvFnintF7eP30DjX+nAdLDAGOZwSflhijQyVwnGtpczNjFrDLUzQ==",
"license": "MIT",
"dependencies": {
"accessor-fn": "1",
"kapsule": "^1.16",
"three": ">=0.118 <1",
"three-forcegraph": "1",
"three-render-objects": "^1.35"
},
"engines": {
"node": ">=12"
}
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/abort-controller/-/abort-controller-3.0.0.tgz",
"integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
"dependencies": {
"event-target-shim": "^5.0.0"
},
"engines": {
"node": ">=6.5"
}
},
"node_modules/accessor-fn": {
"version": "1.5.3",
"resolved": "https://registry.npmmirror.com/accessor-fn/-/accessor-fn-1.5.3.tgz",
"integrity": "sha512-rkAofCwe/FvYFUlMB0v0gWmhqtfAtV1IUkdPbfhTUyYniu5LrC0A0UJkTH0Jv3S8SvwkmfuAlY+mQIJATdocMA==",
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/agentkeepalive": {
"version": "4.6.0",
"resolved": "https://registry.npmmirror.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
"dependencies": {
"humanize-ms": "^1.2.1"
},
"engines": {
"node": ">= 8.0.0"
}
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/chokidar": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.3.tgz",
"integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"readdirp": "^4.0.1"
},
"engines": {
"node": ">= 14.16.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
},
"node_modules/core-js": {
"version": "3.46.0",
"resolved": "https://registry.npmmirror.com/core-js/-/core-js-3.46.0.tgz",
"integrity": "sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA==",
"hasInstallScript": true,
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"license": "MIT"
},
"node_modules/d3": {
"version": "6.7.0",
"resolved": "https://registry.npmmirror.com/d3/-/d3-6.7.0.tgz",
"integrity": "sha512-hNHRhe+yCDLUG6Q2LwvR/WdNFPOJQ5VWqsJcwIYVeI401+d2/rrCjxSXkiAdIlpx7/73eApFB4Olsmh3YN7a6g==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-array": "2",
"d3-axis": "2",
"d3-brush": "2",
"d3-chord": "2",
"d3-color": "2",
"d3-contour": "2",
"d3-delaunay": "5",
"d3-dispatch": "2",
"d3-drag": "2",
"d3-dsv": "2",
"d3-ease": "2",
"d3-fetch": "2",
"d3-force": "2",
"d3-format": "2",
"d3-geo": "2",
"d3-hierarchy": "2",
"d3-interpolate": "2",
"d3-path": "2",
"d3-polygon": "2",
"d3-quadtree": "2",
"d3-random": "2",
"d3-scale": "3",
"d3-scale-chromatic": "2",
"d3-selection": "2",
"d3-shape": "2",
"d3-time": "2",
"d3-time-format": "3",
"d3-timer": "2",
"d3-transition": "2",
"d3-zoom": "2"
}
},
"node_modules/d3-array": {
"version": "2.12.1",
"resolved": "https://registry.npmmirror.com/d3-array/-/d3-array-2.12.1.tgz",
"integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
"license": "BSD-3-Clause",
"dependencies": {
"internmap": "^1.0.0"
}
},
"node_modules/d3-axis": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/d3-axis/-/d3-axis-2.1.0.tgz",
"integrity": "sha512-z/G2TQMyuf0X3qP+Mh+2PimoJD41VOCjViJzT0BHeL/+JQAofkiWZbWxlwFGb1N8EN+Cl/CW+MUKbVzr1689Cw==",
"license": "BSD-3-Clause"
},
"node_modules/d3-binarytree": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/d3-binarytree/-/d3-binarytree-1.0.2.tgz",
"integrity": "sha512-cElUNH+sHu95L04m92pG73t2MEJXKu+GeKUN1TJkFsu93E5W8E9Sc3kHEGJKgenGvj19m6upSn2EunvMgMD2Yw==",
"license": "MIT"
},
"node_modules/d3-brush": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/d3-brush/-/d3-brush-2.1.0.tgz",
"integrity": "sha512-cHLLAFatBATyIKqZOkk/mDHUbzne2B3ZwxkzMHvFTCZCmLaXDpZRihQSn8UNXTkGD/3lb/W2sQz0etAftmHMJQ==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-dispatch": "1 - 2",
"d3-drag": "2",
"d3-interpolate": "1 - 2",
"d3-selection": "2",
"d3-transition": "2"
}
},
"node_modules/d3-chord": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-chord/-/d3-chord-2.0.0.tgz",
"integrity": "sha512-D5PZb7EDsRNdGU4SsjQyKhja8Zgu+SHZfUSO5Ls8Wsn+jsAKUUGkcshLxMg9HDFxG3KqavGWaWkJ8EpU8ojuig==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-path": "1 - 2"
}
},
"node_modules/d3-color": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-color/-/d3-color-2.0.0.tgz",
"integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==",
"license": "BSD-3-Clause"
},
"node_modules/d3-context-menu": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/d3-context-menu/-/d3-context-menu-1.1.2.tgz",
"integrity": "sha512-lcw3Pjtv9+T41W5SKxNsNYrKBMBN5Dse/b3kIfbpee1YTkziInG1RLVcTuL6BYQlux9bRr6tooEnenDj7wv0bA==",
"license": "MIT"
},
"node_modules/d3-contour": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-contour/-/d3-contour-2.0.0.tgz",
"integrity": "sha512-9unAtvIaNk06UwqBmvsdHX7CZ+NPDZnn8TtNH1myW93pWJkhsV25JcgnYAu0Ck5Veb1DHiCv++Ic5uvJ+h50JA==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-array": "2"
}
},
"node_modules/d3-delaunay": {
"version": "5.3.0",
"resolved": "https://registry.npmmirror.com/d3-delaunay/-/d3-delaunay-5.3.0.tgz",
"integrity": "sha512-amALSrOllWVLaHTnDLHwMIiz0d1bBu9gZXd1FiLfXf8sHcX9jrcj81TVZOqD4UX7MgBZZ07c8GxzEgBpJqc74w==",
"license": "ISC",
"dependencies": {
"delaunator": "4"
}
},
"node_modules/d3-dispatch": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
"integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==",
"license": "BSD-3-Clause"
},
"node_modules/d3-drag": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-drag/-/d3-drag-2.0.0.tgz",
"integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-dispatch": "1 - 2",
"d3-selection": "2"
}
},
"node_modules/d3-dsv": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-dsv/-/d3-dsv-2.0.0.tgz",
"integrity": "sha512-E+Pn8UJYx9mViuIUkoc93gJGGYut6mSDKy2+XaPwccwkRGlR+LO97L2VCCRjQivTwLHkSnAJG7yo00BWY6QM+w==",
"license": "BSD-3-Clause",
"dependencies": {
"commander": "2",
"iconv-lite": "0.4",
"rw": "1"
},
"bin": {
"csv2json": "bin/dsv2json",
"csv2tsv": "bin/dsv2dsv",
"dsv2dsv": "bin/dsv2dsv",
"dsv2json": "bin/dsv2json",
"json2csv": "bin/json2dsv",
"json2dsv": "bin/json2dsv",
"json2tsv": "bin/json2dsv",
"tsv2csv": "bin/dsv2dsv",
"tsv2json": "bin/dsv2json"
}
},
"node_modules/d3-ease": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-ease/-/d3-ease-2.0.0.tgz",
"integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==",
"license": "BSD-3-Clause"
},
"node_modules/d3-fetch": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-fetch/-/d3-fetch-2.0.0.tgz",
"integrity": "sha512-TkYv/hjXgCryBeNKiclrwqZH7Nb+GaOwo3Neg24ZVWA3MKB+Rd+BY84Nh6tmNEMcjUik1CSUWjXYndmeO6F7sw==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-dsv": "1 - 2"
}
},
"node_modules/d3-force": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/d3-force/-/d3-force-2.1.1.tgz",
"integrity": "sha512-nAuHEzBqMvpFVMf9OX75d00OxvOXdxY+xECIXjW6Gv8BRrXu6gAWbv/9XKrvfJ5i5DCokDW7RYE50LRoK092ew==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-dispatch": "1 - 2",
"d3-quadtree": "1 - 2",
"d3-timer": "1 - 2"
}
},
"node_modules/d3-force-3d": {
"version": "3.0.6",
"resolved": "https://registry.npmmirror.com/d3-force-3d/-/d3-force-3d-3.0.6.tgz",
"integrity": "sha512-4tsKHUPLOVkyfEffZo1v6sFHvGFwAIIjt/W8IThbp08DYAsXZck+2pSHEG5W1+gQgEvFLdZkYvmJAbRM2EzMnA==",
"license": "MIT",
"dependencies": {
"d3-binarytree": "1",
"d3-dispatch": "1 - 3",
"d3-octree": "1",
"d3-quadtree": "1 - 3",
"d3-timer": "1 - 3"
},
"engines": {
"node": ">=12"
}
},
"node_modules/d3-format": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-format/-/d3-format-2.0.0.tgz",
"integrity": "sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==",
"license": "BSD-3-Clause"
},
"node_modules/d3-geo": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/d3-geo/-/d3-geo-2.0.2.tgz",
"integrity": "sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-array": "^2.5.0"
}
},
"node_modules/d3-hierarchy": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-hierarchy/-/d3-hierarchy-2.0.0.tgz",
"integrity": "sha512-SwIdqM3HxQX2214EG9GTjgmCc/mbSx4mQBn+DuEETubhOw6/U3fmnji4uCVrmzOydMHSO1nZle5gh6HB/wdOzw==",
"license": "BSD-3-Clause"
},
"node_modules/d3-interpolate": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
"integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-color": "1 - 2"
}
},
"node_modules/d3-octree": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/d3-octree/-/d3-octree-1.1.0.tgz",
"integrity": "sha512-F8gPlqpP+HwRPMO/8uOu5wjH110+6q4cgJvgJT6vlpy3BEaDIKlTZrgHKZSp/i1InRpVfh4puY/kvL6MxK930A==",
"license": "MIT"
},
"node_modules/d3-path": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-path/-/d3-path-2.0.0.tgz",
"integrity": "sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==",
"license": "BSD-3-Clause"
},
"node_modules/d3-polygon": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-polygon/-/d3-polygon-2.0.0.tgz",
"integrity": "sha512-MsexrCK38cTGermELs0cO1d79DcTsQRN7IWMJKczD/2kBjzNXxLUWP33qRF6VDpiLV/4EI4r6Gs0DAWQkE8pSQ==",
"license": "BSD-3-Clause"
},
"node_modules/d3-quadtree": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-quadtree/-/d3-quadtree-2.0.0.tgz",
"integrity": "sha512-b0Ed2t1UUalJpc3qXzKi+cPGxeXRr4KU9YSlocN74aTzp6R/Ud43t79yLLqxHRWZfsvWXmbDWPpoENK1K539xw==",
"license": "BSD-3-Clause"
},
"node_modules/d3-random": {
"version": "2.2.2",
"resolved": "https://registry.npmmirror.com/d3-random/-/d3-random-2.2.2.tgz",
"integrity": "sha512-0D9P8TRj6qDAtHhRQn6EfdOtHMfsUWanl3yb/84C4DqpZ+VsgfI5iTVRNRbELCfNvRfpMr8OrqqUTQ6ANGCijw==",
"license": "BSD-3-Clause"
},
"node_modules/d3-scale": {
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/d3-scale/-/d3-scale-3.3.0.tgz",
"integrity": "sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-array": "^2.3.0",
"d3-format": "1 - 2",
"d3-interpolate": "1.2.0 - 2",
"d3-time": "^2.1.1",
"d3-time-format": "2 - 3"
}
},
"node_modules/d3-scale-chromatic": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-scale-chromatic/-/d3-scale-chromatic-2.0.0.tgz",
"integrity": "sha512-LLqy7dJSL8yDy7NRmf6xSlsFZ6zYvJ4BcWFE4zBrOPnQERv9zj24ohnXKRbyi9YHnYV+HN1oEO3iFK971/gkzA==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-color": "1 - 2",
"d3-interpolate": "1 - 2"
}
},
"node_modules/d3-selection": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-selection/-/d3-selection-2.0.0.tgz",
"integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==",
"license": "BSD-3-Clause"
},
"node_modules/d3-shape": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/d3-shape/-/d3-shape-2.1.0.tgz",
"integrity": "sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-path": "1 - 2"
}
},
"node_modules/d3-time": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/d3-time/-/d3-time-2.1.1.tgz",
"integrity": "sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-array": "2"
}
},
"node_modules/d3-time-format": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/d3-time-format/-/d3-time-format-3.0.0.tgz",
"integrity": "sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-time": "1 - 2"
}
},
"node_modules/d3-timer": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-timer/-/d3-timer-2.0.0.tgz",
"integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==",
"license": "BSD-3-Clause"
},
"node_modules/d3-transition": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-transition/-/d3-transition-2.0.0.tgz",
"integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-color": "1 - 2",
"d3-dispatch": "1 - 2",
"d3-ease": "1 - 2",
"d3-interpolate": "1 - 2",
"d3-timer": "1 - 2"
},
"peerDependencies": {
"d3-selection": "2"
}
},
"node_modules/d3-zoom": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/d3-zoom/-/d3-zoom-2.0.0.tgz",
"integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==",
"license": "BSD-3-Clause",
"dependencies": {
"d3-dispatch": "1 - 2",
"d3-drag": "2",
"d3-interpolate": "1 - 2",
"d3-selection": "2",
"d3-transition": "2"
}
},
"node_modules/data-bind-mapper": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/data-bind-mapper/-/data-bind-mapper-1.0.3.tgz",
"integrity": "sha512-QmU3lyEnbENQPo0M1F9BMu4s6cqNNp8iJA+b/HP2sSb7pf3dxwF3+EP1eO69rwBfH9kFJ1apmzrtogAmVt2/Xw==",
"license": "MIT",
"dependencies": {
"accessor-fn": "1"
},
"engines": {
"node": ">=12"
}
},
"node_modules/delaunator": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/delaunator/-/delaunator-4.0.1.tgz",
"integrity": "sha512-WNPWi1IRKZfCt/qIDMfERkDp93+iZEmOxN2yy4Jg+Xhv8SLk2UTqqbe1sfiipn0and9QrE914/ihdx82Y/Giag==",
"license": "ISC"
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"peer": true,
"bin": {
"detect-libc": "bin/detect-libc.js"
},
"engines": {
"node": ">=0.10"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/esbuild": {
"version": "0.21.5",
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz",
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=12"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.21.5",
"@esbuild/android-arm": "0.21.5",
"@esbuild/android-arm64": "0.21.5",
"@esbuild/android-x64": "0.21.5",
"@esbuild/darwin-arm64": "0.21.5",
"@esbuild/darwin-x64": "0.21.5",
"@esbuild/freebsd-arm64": "0.21.5",
"@esbuild/freebsd-x64": "0.21.5",
"@esbuild/linux-arm": "0.21.5",
"@esbuild/linux-arm64": "0.21.5",
"@esbuild/linux-ia32": "0.21.5",
"@esbuild/linux-loong64": "0.21.5",
"@esbuild/linux-mips64el": "0.21.5",
"@esbuild/linux-ppc64": "0.21.5",
"@esbuild/linux-riscv64": "0.21.5",
"@esbuild/linux-s390x": "0.21.5",
"@esbuild/linux-x64": "0.21.5",
"@esbuild/netbsd-x64": "0.21.5",
"@esbuild/openbsd-x64": "0.21.5",
"@esbuild/sunos-x64": "0.21.5",
"@esbuild/win32-arm64": "0.21.5",
"@esbuild/win32-ia32": "0.21.5",
"@esbuild/win32-x64": "0.21.5"
}
},
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"node_modules/event-target-shim": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/event-target-shim/-/event-target-shim-5.0.1.tgz",
"integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
"engines": {
"node": ">=6"
}
},
"node_modules/float-tooltip": {
"version": "1.7.5",
"resolved": "https://registry.npmmirror.com/float-tooltip/-/float-tooltip-1.7.5.tgz",
"integrity": "sha512-/kXzuDnnBqyyWyhDMH7+PfP8J/oXiAavGzcRxASOMRHFuReDtofizLLJsf7nnDLAfEaMW4pVWaXrAjtnglpEkg==",
"license": "MIT",
"dependencies": {
"d3-selection": "2 - 3",
"kapsule": "^1.16",
"preact": "10"
},
"engines": {
"node": ">=12"
}
},
"node_modules/form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/form-data-encoder": {
"version": "1.7.2",
"resolved": "https://registry.npmmirror.com/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
"integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="
},
"node_modules/formdata-node": {
"version": "4.4.1",
"resolved": "https://registry.npmmirror.com/formdata-node/-/formdata-node-4.4.1.tgz",
"integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
"dependencies": {
"node-domexception": "1.0.0",
"web-streams-polyfill": "4.0.0-beta.3"
},
"engines": {
"node": ">= 12.20"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/humanize-ms": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
"dependencies": {
"ms": "^2.0.0"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"license": "MIT",
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/immutable": {
"version": "5.1.4",
"resolved": "https://registry.npmmirror.com/immutable/-/immutable-5.1.4.tgz",
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/internmap": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/internmap/-/internmap-1.0.1.tgz",
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
"license": "ISC"
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/kapsule": {
"version": "1.16.3",
"resolved": "https://registry.npmmirror.com/kapsule/-/kapsule-1.16.3.tgz",
"integrity": "sha512-4+5mNNf4vZDSwPhKprKwz3330iisPrb08JyMgbsdFrimBCKNHecua/WBwvVg3n7vwx0C1ARjfhwIpbrbd9n5wg==",
"license": "MIT",
"dependencies": {
"lodash-es": "4"
},
"engines": {
"node": ">=12"
}
},
"node_modules/lodash-es": {
"version": "4.17.21",
"resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz",
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz",
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/marked": {
"version": "12.0.2",
"resolved": "https://registry.npmmirror.com/marked/-/marked-12.0.2.tgz",
"integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==",
"bin": {
"marked": "bin/marked.js"
},
"engines": {
"node": ">= 18"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
},
"node_modules/nanoid": {
"version": "3.3.11",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/ngraph.events": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/ngraph.events/-/ngraph.events-1.4.0.tgz",
"integrity": "sha512-NeDGI4DSyjBNBRtA86222JoYietsmCXbs8CEB0dZ51Xeh4lhVl1y3wpWLumczvnha8sFQIW4E0vvVWwgmX2mGw==",
"license": "BSD-3-Clause"
},
"node_modules/ngraph.forcelayout": {
"version": "3.3.1",
"resolved": "https://registry.npmmirror.com/ngraph.forcelayout/-/ngraph.forcelayout-3.3.1.tgz",
"integrity": "sha512-MKBuEh1wujyQHFTW57y5vd/uuEOK0XfXYxm3lC7kktjJLRdt/KEKEknyOlc6tjXflqBKEuYBBcu7Ax5VY+S6aw==",
"license": "BSD-3-Clause",
"dependencies": {
"ngraph.events": "^1.0.0",
"ngraph.merge": "^1.0.0",
"ngraph.random": "^1.0.0"
}
},
"node_modules/ngraph.graph": {
"version": "20.1.0",
"resolved": "https://registry.npmmirror.com/ngraph.graph/-/ngraph.graph-20.1.0.tgz",
"integrity": "sha512-1jorNgIc0Kg0L9bTNN4+RCrVvbZ+4pqGVMrbhX3LLyqYcRdLvAQRRnxddmfj9l5f6Eq59SUTfbYZEm8cktiE7Q==",
"license": "BSD-3-Clause",
"dependencies": {
"ngraph.events": "^1.2.1"
}
},
"node_modules/ngraph.merge": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/ngraph.merge/-/ngraph.merge-1.0.0.tgz",
"integrity": "sha512-5J8YjGITUJeapsomtTALYsw7rFveYkM+lBj3QiYZ79EymQcuri65Nw3knQtFxQBU1r5iOaVRXrSwMENUPK62Vg==",
"license": "MIT"
},
"node_modules/ngraph.random": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/ngraph.random/-/ngraph.random-1.2.0.tgz",
"integrity": "sha512-4EUeAGbB2HWX9njd6bP6tciN6ByJfoaAvmVL9QTaZSeXrW46eNGA9GajiXiPBbvFqxUWFkEbyo6x5qsACUuVfA==",
"license": "BSD-3-Clause"
},
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "2.7.0",
"resolved": "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/openai": {
"version": "4.83.0",
"resolved": "https://registry.npmmirror.com/openai/-/openai-4.83.0.tgz",
"integrity": "sha512-fmTsqud0uTtRKsPC7L8Lu55dkaTwYucqncDHzVvO64DKOpNTuiYwjbR/nVgpapXuYy8xSnhQQPUm+3jQaxICgw==",
"dependencies": {
"@types/node": "^18.11.18",
"@types/node-fetch": "^2.6.4",
"abort-controller": "^3.0.0",
"agentkeepalive": "^4.2.1",
"form-data-encoder": "1.7.2",
"formdata-node": "^4.3.2",
"node-fetch": "^2.6.7"
},
"bin": {
"openai": "bin/cli"
},
"peerDependencies": {
"ws": "^8.18.0",
"zod": "^3.23.8"
},
"peerDependenciesMeta": {
"ws": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/polished": {
"version": "4.3.1",
"resolved": "https://registry.npmmirror.com/polished/-/polished-4.3.1.tgz",
"integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==",
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.17.8"
},
"engines": {
"node": ">=10"
}
},
"node_modules/postcss": {
"version": "8.5.6",
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"dependencies": {
"nanoid": "^3.3.11",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/preact": {
"version": "10.27.2",
"resolved": "https://registry.npmmirror.com/preact/-/preact-10.27.2.tgz",
"integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/preact"
}
},
"node_modules/readdirp": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz",
"integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">= 14.18.0"
},
"funding": {
"type": "individual",
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/rollup": {
"version": "4.34.6",
"resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.34.6.tgz",
"integrity": "sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==",
"dev": true,
"dependencies": {
"@types/estree": "1.0.6"
},
"bin": {
"rollup": "dist/bin/rollup"
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.34.6",
"@rollup/rollup-android-arm64": "4.34.6",
"@rollup/rollup-darwin-arm64": "4.34.6",
"@rollup/rollup-darwin-x64": "4.34.6",
"@rollup/rollup-freebsd-arm64": "4.34.6",
"@rollup/rollup-freebsd-x64": "4.34.6",
"@rollup/rollup-linux-arm-gnueabihf": "4.34.6",
"@rollup/rollup-linux-arm-musleabihf": "4.34.6",
"@rollup/rollup-linux-arm64-gnu": "4.34.6",
"@rollup/rollup-linux-arm64-musl": "4.34.6",
"@rollup/rollup-linux-loongarch64-gnu": "4.34.6",
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.6",
"@rollup/rollup-linux-riscv64-gnu": "4.34.6",
"@rollup/rollup-linux-s390x-gnu": "4.34.6",
"@rollup/rollup-linux-x64-gnu": "4.34.6",
"@rollup/rollup-linux-x64-musl": "4.34.6",
"@rollup/rollup-win32-arm64-msvc": "4.34.6",
"@rollup/rollup-win32-ia32-msvc": "4.34.6",
"@rollup/rollup-win32-x64-msvc": "4.34.6",
"fsevents": "~2.3.2"
}
},
"node_modules/rw": {
"version": "1.3.3",
"resolved": "https://registry.npmmirror.com/rw/-/rw-1.3.3.tgz",
"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
"license": "BSD-3-Clause"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/sass": {
"version": "1.93.3",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.93.3.tgz",
"integrity": "sha512-elOcIZRTM76dvxNAjqYrucTSI0teAF/L2Lv0s6f6b7FOwcwIuA357bIE871580AjHJuSvLIRUosgV+lIWx6Rgg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"chokidar": "^4.0.0",
"immutable": "^5.0.2",
"source-map-js": ">=0.6.2 <2.0.0"
},
"bin": {
"sass": "sass.js"
},
"engines": {
"node": ">=14.0.0"
},
"optionalDependencies": {
"@parcel/watcher": "^2.4.1"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/terser": {
"version": "5.44.0",
"resolved": "https://registry.npmmirror.com/terser/-/terser-5.44.0.tgz",
"integrity": "sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==",
"dev": true,
"license": "BSD-2-Clause",
"optional": true,
"peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/terser/node_modules/acorn": {
"version": "8.15.0",
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.15.0.tgz",
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/three": {
"version": "0.181.0",
"resolved": "https://registry.npmmirror.com/three/-/three-0.181.0.tgz",
"integrity": "sha512-KGf6EOCOQGshXeleKxpxhbowQwAXR2dLlD93egHtZ9Qmk07Saf8sXDR+7wJb53Z1ORZiatZ4WGST9UsVxhHEbg==",
"license": "MIT"
},
"node_modules/three-forcegraph": {
"version": "1.43.0",
"resolved": "https://registry.npmmirror.com/three-forcegraph/-/three-forcegraph-1.43.0.tgz",
"integrity": "sha512-1AqLmTCjjjwcuccObG96fCxiRnNJjCLdA5Mozl7XK+ROwTJ6QEJPo2XJ6uxWeuAmPE7ukMhgv4lj28oZSfE4wg==",
"license": "MIT",
"dependencies": {
"accessor-fn": "1",
"d3-array": "1 - 3",
"d3-force-3d": "2 - 3",
"d3-scale": "1 - 4",
"d3-scale-chromatic": "1 - 3",
"data-bind-mapper": "1",
"kapsule": "^1.16",
"ngraph.forcelayout": "3",
"ngraph.graph": "20",
"tinycolor2": "1"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"three": ">=0.118.3"
}
},
"node_modules/three-render-objects": {
"version": "1.40.4",
"resolved": "https://registry.npmmirror.com/three-render-objects/-/three-render-objects-1.40.4.tgz",
"integrity": "sha512-Ukpu1pei3L5r809izvjsZxwuRcYLiyn6Uvy3lZ9bpMTdvj3i6PeX6w++/hs2ZS3KnEzGjb6YvTvh4UQuwHTDJg==",
"license": "MIT",
"dependencies": {
"@tweenjs/tween.js": "18 - 25",
"accessor-fn": "1",
"float-tooltip": "^1.7",
"kapsule": "^1.16",
"polished": "4"
},
"engines": {
"node": ">=12"
},
"peerDependencies": {
"three": ">=0.168"
}
},
"node_modules/three-spritetext": {
"version": "1.10.0",
"resolved": "https://registry.npmmirror.com/three-spritetext/-/three-spritetext-1.10.0.tgz",
"integrity": "sha512-t08iP1FCU1lQh8T5MmCpdijKgas8GDHJE0LqMGBuVu3xqMMpFnEZhTlih7FlxLPQizHIGoumUSpfOlY1GO/Tgg==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"peerDependencies": {
"three": ">=0.86.0"
}
},
"node_modules/tinycolor2": {
"version": "1.6.0",
"resolved": "https://registry.npmmirror.com/tinycolor2/-/tinycolor2-1.6.0.tgz",
"integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
"license": "MIT"
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/uuid": {
"version": "11.1.0",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-11.1.0.tgz",
"integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist/esm/bin/uuid"
}
},
"node_modules/vite": {
"version": "5.4.14",
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.14.tgz",
"integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==",
"dev": true,
"dependencies": {
"esbuild": "^0.21.3",
"postcss": "^8.4.43",
"rollup": "^4.20.0"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
},
"optionalDependencies": {
"fsevents": "~2.3.3"
},
"peerDependencies": {
"@types/node": "^18.0.0 || >=20.0.0",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
"sass-embedded": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
"less": {
"optional": true
},
"lightningcss": {
"optional": true
},
"sass": {
"optional": true
},
"sass-embedded": {
"optional": true
},
"stylus": {
"optional": true
},
"sugarss": {
"optional": true
},
"terser": {
"optional": true
}
}
},
"node_modules/vue": {
"version": "3.5.22",
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.22.tgz",
"integrity": "sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==",
"license": "MIT",
"dependencies": {
"@vue/compiler-dom": "3.5.22",
"@vue/compiler-sfc": "3.5.22",
"@vue/runtime-dom": "3.5.22",
"@vue/server-renderer": "3.5.22",
"@vue/shared": "3.5.22"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/vue-router": {
"version": "4.6.3",
"resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.6.3.tgz",
"integrity": "sha512-ARBedLm9YlbvQomnmq91Os7ck6efydTSpRP3nuOKCvgJOHNrhRoJDSKtee8kcL1Vf7nz6U+PMBL+hTvR3bTVQg==",
"license": "MIT",
"dependencies": {
"@vue/devtools-api": "^6.6.4"
},
"funding": {
"url": "https://github.com/sponsors/posva"
},
"peerDependencies": {
"vue": "^3.5.0"
}
},
"node_modules/vuex": {
"version": "4.1.0",
"resolved": "https://registry.npmmirror.com/vuex/-/vuex-4.1.0.tgz",
"integrity": "sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==",
"license": "MIT",
"dependencies": {
"@vue/devtools-api": "^6.0.0-beta.11"
},
"peerDependencies": {
"vue": "^3.2.0"
}
},
"node_modules/web-streams-polyfill": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmmirror.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
"integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==",
"engines": {
"node": ">= 14"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/ws": {
"version": "8.18.3",
"resolved": "https://registry.npmmirror.com/ws/-/ws-8.18.3.tgz",
"integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==",
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
}
}
{
"name": "deepseek-chat",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"marked": "^12.0.0",
"openai": "^4.28.0",
"uuid": "^11.1.0",
"vue": "^3.3.0",
"vue-router": "^4.0.0",
"vuex": "^4.0.0",
"3d-force-graph": "^1.67.6",
"three-spritetext": "^1.5.3",
"core-js": "^3.6.5",
"d3": "^6.2.0",
"d3-context-menu": "^1.1.2"
},
"devDependencies": {
"vite": "^5.0.0",
"@vitejs/plugin-vue": "^4.0.0"
}
}
<template>
<router-view />
</template>
<script setup>
// App.vue 现在只作为路由的入口点
// 所有的布局和导航逻辑都移到 Layout.vue 中
</script>
<style>
/* 全局样式可以保留在这里 */
</style>
\ No newline at end of file
<template>
<div class="input-container">
<div class="input-wrapper">
<textarea
class="chat-input"
v-model="message"
@keydown.enter.prevent="sendMessage"
placeholder="输入消息,按回车发送..."
rows="1"
ref="textarea"
:disabled="isLoading"
></textarea>
<button
class="send-btn"
@click="sendMessage"
:disabled="isLoading || !message.trim()"
>
发送
</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
const props = defineProps({
isLoading: {
type: Boolean,
default: false
}
});
const message = ref('');
const textarea = ref(null);
const emit = defineEmits(['send']);
const sendMessage = () => {
if (message.value.trim()) {
emit('send', message.value);
message.value = '';
}
};
</script>
<style scoped>
.input-container {
position: absolute;
bottom: 60px;
left: 0;
right: 0;
padding: 20px 40px;
background: linear-gradient(to bottom, transparent, var(--bg-color) 20%);
}
:global(.dark-mode) .input-container {
--bg-color: #1a1b1e;
}
.input-wrapper {
position: relative;
max-width: 800px;
margin: 0 auto;
display: flex;
gap: 12px;
align-items: flex-start;
background: white;
border-radius: 12px;
box-shadow: 0 0 15px rgba(0, 0, 0, 0.1);
padding: 12px;
border: 1px solid #eee;
transition: all 0.3s ease;
}
:global(.dark-mode) .input-wrapper {
background: #2d3748;
border-color: rgba(255, 255, 255, 0.1);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
}
.chat-input {
flex: 1;
padding: 8px 12px;
border-radius: 8px;
border: 1px solid transparent;
background-color: transparent;
color: #333;
resize: none;
font-size: 14px;
line-height: 1.5;
transition: all 0.3s ease;
height: 24px;
min-height: 24px;
outline: none;
}
:global(.dark-mode) .chat-input {
color: #e2e8f0;
}
:global(.dark-mode) .chat-input::placeholder {
color: #a0aec0;
}
.chat-input:focus {
border-color: #e6e6e6;
}
:global(.dark-mode) .chat-input:focus {
border-color: rgba(255, 255, 255, 0.2);
}
.send-btn {
padding: 8px 20px;
border: none;
border-radius: 6px;
background-color: #4a5568;
color: white;
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
height: 36px;
}
.send-btn:hover {
background-color: #2d3748;
}
:global(.dark-mode) .send-btn {
background-color: #63b3ed;
}
:global(.dark-mode) .send-btn:hover {
background-color: #4299e1;
}
.send-btn:disabled {
opacity: 0.6;
cursor: not-allowed;
}
:global(.dark-mode) .send-btn:disabled {
background-color: #718096;
}
.chat-input:disabled {
background-color: #f5f5f5;
cursor: not-allowed;
}
:global(.dark-mode) .chat-input:disabled {
background-color: rgba(45, 55, 72, 0.5);
}
</style>
\ No newline at end of file
<template>
<div :class="['message', `${role}-message`]">
<div class="message-content">
<template v-if="role === 'assistant'">
<div v-if="reasoning" class="thinking-section">
<div class="thinking-header" @click="toggleThinking">
<span class="toggle-icon">{{ isThinkingExpanded ? '▼' : '▶' }}</span>
思考过程
</div>
<div class="thinking-content" v-show="isThinkingExpanded" v-html="formattedReasoning"></div>
</div>
<div v-if="content && !isThinking" class="answer-content" v-html="formattedContent"></div>
<div v-if="isThinking" class="thinking-indicator" v-html="formattedContent"></div>
</template>
<div v-else v-html="formattedContent"></div>
</div>
</div>
</template>
<script setup>
import { computed, ref, watch } from 'vue';
import { marked } from 'marked';
const props = defineProps({
content: {
type: String,
required: true
},
role: {
type: String,
required: true
},
isThinking: {
type: Boolean,
default: false
},
reasoning: {
type: String,
default: ''
}
});
// 默认关闭,只有在生成新内容时才打开
const isThinkingExpanded = ref(false);
// 用于跟踪是否是新生成的消息
const isNewMessage = ref(false);
// 监听 reasoning 的变化
watch(() => props.reasoning, (newVal, oldVal) => {
// 如果是从空变为有内容,说明是新生成的思考过程,则展开
if (!oldVal && newVal) {
isThinkingExpanded.value = true;
isNewMessage.value = true;
}
// 如果直接设置了完整内容(加载历史消息时),则保持折叠
});
// 监听 isThinking 的变化
watch(() => props.isThinking, (newVal) => {
// 当开始思考时展开
if (newVal) {
isThinkingExpanded.value = true;
isNewMessage.value = true;
}
// 当思考完成时,如果是新消息则保持展开
else if (isNewMessage.value) {
isThinkingExpanded.value = true;
}
});
const formattedContent = computed(() => {
return marked(props.content);
});
const formattedReasoning = computed(() => {
return marked(props.reasoning);
});
const toggleThinking = () => {
isThinkingExpanded.value = !isThinkingExpanded.value;
};
</script>
<style scoped>
.message {
display: flex;
padding: 16px 20px;
position: relative;
}
:global(.dark-mode) .user-message {
background-color: rgba(45, 55, 72, 0.3);
}
:global(.dark-mode) .user-message .message-content {
color: #e2e8f0;
}
:global(.dark-mode) .assistant-message {
background-color: rgba(45, 55, 72, 0.2);
}
:global(.dark-mode) .assistant-message .message-content {
color: #e2e8f0;
}
:global(.dark-mode) .thinking-section {
border-color: rgba(255, 255, 255, 0.1);
background: rgba(45, 55, 72, 0.3);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}
:global(.dark-mode) .thinking-header {
background-color: rgba(45, 55, 72, 0.4);
color: #e2e8f0;
border-bottom-color: rgba(255, 255, 255, 0.1);
}
:global(.dark-mode) .thinking-header:hover {
background-color: rgba(45, 55, 72, 0.5);
}
:global(.dark-mode) .toggle-icon {
color: #a0aec0;
}
:global(.dark-mode) .thinking-content {
background-color: rgba(45, 55, 72, 0.2);
color: #e2e8f0;
}
:global(.dark-mode) .message-content :deep(pre) {
background-color: rgba(26, 32, 44, 0.95);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}
:global(.dark-mode) .message-content :deep(code) {
background-color: rgba(45, 55, 72, 0.3);
color: #e2e8f0;
}
:global(.dark-mode) .thinking-indicator {
color: #a0aec0;
}
.user-message {
background-color: rgba(241, 243, 245, 0.7);
}
.user-message .message-content {
color: #2d3748;
font-weight: 500;
}
.assistant-message {
background-color: rgba(255, 255, 255, 0.7);
}
.assistant-message .message-content {
color: #2d3748;
}
.message-content {
flex: 1;
max-width: 100%;
margin: 0 auto;
line-height: 1.6;
}
.message + .message {
border-top: 1px solid rgba(0, 0, 0, 0.03);
}
.thinking-section {
border: 1px solid rgba(0, 0, 0, 0.06);
border-radius: 8px;
margin: 8px 0;
overflow: hidden;
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.03);
}
.thinking-header {
padding: 10px 16px;
background-color: rgba(241, 243, 245, 0.7);
cursor: pointer;
display: flex;
align-items: center;
font-size: 14px;
user-select: none;
transition: all 0.2s ease;
color: #4a5568;
border-bottom: 1px solid rgba(0, 0, 0, 0.04);
}
.thinking-header:hover {
background-color: rgba(237, 239, 241, 0.9);
color: #2d3748;
}
.toggle-icon {
margin-right: 8px;
font-size: 12px;
transition: transform 0.3s ease;
color: #718096;
}
.thinking-content {
padding: 16px;
font-size: 14px;
line-height: 1.6;
background-color: rgba(255, 255, 255, 0.7);
color: #4a5568;
}
.message-content :deep(pre) {
background-color: rgba(45, 55, 72, 0.97);
padding: 16px;
border-radius: 8px;
overflow-x: auto;
margin: 12px 0;
font-family: 'Fira Code', monospace;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.message-content :deep(code) {
background-color: rgba(45, 55, 72, 0.06);
padding: 2px 6px;
border-radius: 4px;
font-family: 'Fira Code', monospace;
font-size: 0.9em;
color: #2d3748;
}
.message-content :deep(p) {
margin: 8px 0;
line-height: 1.6;
}
.message-content :deep(ul), .message-content :deep(ol) {
margin: 8px 0;
padding-left: 24px;
}
.message-content :deep(li) {
margin: 4px 0;
}
.answer-content {
margin-top: 8px;
color: inherit;
}
.thinking-indicator {
color: #718096;
font-style: italic;
animation: thinking 1.5s infinite;
padding: 8px 0;
}
@keyframes thinking {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
</style>
\ No newline at end of file
<template>
<Transition name="modal">
<div v-if="modelValue" class="modal-overlay" @click="$emit('update:modelValue', false)">
<div class="modal-content" @click.stop>
<div class="modal-header">
<h3>{{ title }}</h3>
</div>
<div class="modal-body">
{{ message }}
</div>
<div class="modal-footer">
<button class="btn btn-cancel" @click="$emit('update:modelValue', false)">取消</button>
<button class="btn btn-confirm" @click="confirm">确认</button>
</div>
</div>
</div>
</Transition>
</template>
<script setup>
defineProps({
modelValue: Boolean,
title: {
type: String,
default: '确认'
},
message: {
type: String,
required: true
}
});
const emit = defineEmits(['update:modelValue', 'confirm']);
const confirm = () => {
emit('update:modelValue', false);
emit('confirm');
};
</script>
<style scoped>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content {
background-color: var(--chat-background);
border-radius: 8px;
width: 90%;
max-width: 400px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.modal-header {
padding: 16px 20px;
border-bottom: 1px solid #565869;
}
.modal-header h3 {
margin: 0;
font-size: 1.2em;
color: var(--text-color);
}
.modal-body {
padding: 20px;
color: var(--text-color);
line-height: 1.5;
}
.modal-footer {
padding: 16px 20px;
border-top: 1px solid #565869;
display: flex;
justify-content: flex-end;
gap: 12px;
}
.btn {
padding: 8px 16px;
border-radius: 4px;
border: 1px solid #565869;
background-color: transparent;
color: var(--text-color);
cursor: pointer;
transition: all 0.2s;
}
.btn-cancel:hover {
background-color: #40414f;
}
.btn-confirm {
background-color: var(--primary-color);
border-color: var(--primary-color);
}
.btn-confirm:hover {
opacity: 0.9;
}
/* 过渡动画 */
.modal-enter-active,
.modal-leave-active {
transition: opacity 0.3s ease;
}
.modal-enter-from,
.modal-leave-to {
opacity: 0;
}
.modal-enter-active .modal-content {
animation: modal-in 0.3s ease-out;
}
.modal-leave-active .modal-content {
animation: modal-in 0.3s ease-out reverse;
}
@keyframes modal-in {
from {
transform: translateY(-20px);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
</style>
\ No newline at end of file
<template>
<div>
<!-- 绘制模式选择 -->
<div id="mode">
<h3>文字搜索</h3>
<div class="gState" style="margin-bottom: 20px;">
<span
@click="changeTextState(0)"
:class="{ active: isShowText }"
style="border-top-right-radius:0;border-bottom-right-radius:0;"
>显示</span>
<!-- <span
@click="changeNodeState(1)"
:class="{ active: nodeState === 1 }"
style="border-top-left-radius:0;border-bottom-left-radius:0;position:relative;left:-5px;"
>关系(度)</span> -->
<span
@click="changeTextState(2)"
:class="{ active: textState === 2 }"
style="border-top-left-radius:0;border-bottom-left-radius:0;position:relative;left:-5px;"
>隐藏</span>
</div>
<el-input @input="searchKeyWords" v-model="keywords" clearable placeholder="请输入内容" />
<p class="font-sky" style="text-align: left;">
<strong>节点个数:{{ nodes.length }}</strong>
<br>
<strong>关系个数:{{ links.length }}</strong>
<br>
<strong>平均度数:{{ gDegree }}</strong>
<br>
<strong>图密度:{{ gDensity }}</strong>
<br>
<strong>稀疏度:{{ gSparsity }}</strong>
</p>
</div>
<svg
id="svg"
width="1200"
height="750"
></svg>
<!-- 绘制图例 -->
<div id="indicator">
<!-- 利用item 遍历一个数组 利用index 遍历另外一个数组 -->
<div v-for="(name, index) in names" :key="index">
<span
@click="hideNodeOfType"
:data-state="states[index]"
:data-index="index"
style="cursor: pointer;"
:style="{ backgroundColor: states[index] === 'on' ? colors[index] : '#aaa' }"
></span>
{{ name }}
</div>
</div>
<!-- 绘制右边显示结果 -->
<div id="info" v-show="selectNodeData.name !== undefined">
<!-- <h4 :style="{ color: selectNodeData.color }">{{ selectNodeData.name }}</h4>
<p v-for="(item, key) in selectNodeData.properties" :key="item">
<span>{{ key }}</span>
{{ item }}
</p> -->
<el-card
:style="{ backgroundColor: selectNodeData.color }"
class="node-card"
>
<div slot="header" class="clearfix">
<span>{{ selectNodeData.name }}</span>
<el-button
@click="btnEdit"
style="float: right; padding: 3px 0;color: #409EFB;font-size: 15px;"
type="text"
>编辑</el-button>
</div>
<div
v-for="(item, key) in selectNodeData.properties" :key="item"
>
<span style="margin-right: 8px;">{{ (nodeObjMap[key] ? nodeObjMap[key] : key) + ':' }}</span>
<span style="text-align: right;"><b>{{ item }}</b></span>
</div>
</el-card>
</div>
<!-- 编辑框 -->
<el-dialog :visible.sync="dialogFormVisible">
<el-form
:model="temp"
label-position="right"
label-width="86px"
style="width: 500px; margin-left:50px;"
>
<el-form-item
v-for="(value, key) in temp"
:key="key"
:label="nodeObjMap[key] ? nodeObjMap[key] : key"
>
<el-input
v-model="temp[key]"
:readonly="!isEdit"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelEdit">
取消
</el-button>
<el-button type="primary" @click="doEdit">
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import * as d3 from 'd3'
// 暂时注释掉contextMenu插件,避免对象不可扩展错误
// import install from '../plugins/d3-context-menu'
// try {
// if (d3 && !d3.contextMenu) {
// install(d3) // 为d3注册右键菜单插件
// }
// } catch (error) {
// console.warn('Context menu plugin registration failed:', error)
// }
export default {
name: 'd3graph',
props: {
data: {
type: Object,
default: function () {
return {
nodes: [],
links: []
}
}
},
/* eslint-disable */
// 自定义图例(数组保证一一对应)
// names 图例名称变量制作图标
// labels 节点的标签名称(与records.json中保证相同)
names: {
type: Array
},
labels: Array,
linkTypes: Array
},
data () {
return {
svgDom: null, // svg的DOM元素 => d3.select('#svg1')
keywords: '',
nodeState: 0,
// 文本状态,表示是否显示文本信息(0:显示/1:不显示)
textState: 0,
// d3render()最终展示到页面上的数据(节点隐藏功能)
nodes: [],
links: [],
/* eslint-disable */
// 自定义图例及颜色(数组保证一一对应)
// colors 图例颜色(9个颜色)
// states 图例状态(on:显示 / off:不显示)
colors: ['#55cccc', '#aaaaff', '#4e88af', '#ca635f','#FFC0CB', '#BA55D3', '#1E90FF', '#7FFFD4','#FFFF00'],
states: [],
selectNodeData: {}, // 选中节点的详细信息展示
isNodeClicked: false, // 是否点击(选中)节点
// 用于位置、大小矫正(暂不使用)
// svgTranslate: [240, 130],
// svgScale: 0.5,
// 右击事件的菜单栏
menu: [
{
title: '隐藏节点',
action: (elm, d) => {
console.log(d)
// 遍历删除节点
this.nodes = this.nodes.filter(node => {
if (node.id === d.id) return false
else return true
})
// 遍历删除关系
this.links = this.links.filter(link => {
if (link.source.id === d.id || link.target.id === d.id) return false
else return true
})
this.d3render() // 重新渲染图
this.stateInit()
},
disabled: false // optional, defaults to false
},
{
title: '显示节点关联图',
action: (elm, d) => {
console.log(d)
// 遍历保留对应节点
this.nodes = this.data.nodes.filter(node => {
if (node.id === d.id) return true
else {
for (var i = 0; i < this.data.links.length; i++) {
// 如果links的起点等于name,并且终点等于正在处理的则显示
if (this.data.links[i].source.id === node.id && this.data.links[i].target.id === d.id) {
return true
}
if (this.data.links[i].target.id === node.id && this.data.links[i].source.id === d.id) {
return true
}
}
return false
}
})
// 遍历保留节点的关联关系
this.links = this.data.links.filter(link => {
if (link.source.id === d.id || link.target.id === d.id) return true
else return false
})
this.d3render() // 重新渲染图
this.stateInit()
}
},
{
title: '显示所有查询节点',
action: (elm, d) => {
this.nodes = this.data.nodes
// 遍历保留节点的关联关系
this.links = this.data.links
this.d3render() // 重新渲染图
this.stateInit()
}
}
],
temp: {}, // 临时存储编辑时的节点信息
dialogFormVisible: false,
isEdit: true,
// 节点属性对应的标签名称
nodeObjMap: {
'address': '注册地址',
'captial': '注册资本',
'credit_code': '信用代码',
'name': '节点名称',
'setup_time': '注册日期'
}
}
},
computed: {
isShowNode: function () {
// `this` 指向 vm 实例
return this.nodeState === 0
},
isShowText: function () {
// `this` 指向 vm 实例
return this.textState === 0
},
gDensity () {
return this.nodes.length <= 1 ? 0 : (this.links.length / (this.nodes.length * (this.nodes.length - 1))).toFixed(2)
},
gDegree () {
return (this.links.length / this.nodes.length).toFixed(2)
},
// 企业实体的平均度数
gMainDegree () {
// 遍历节点
// this.nodes.forEach(node => {
//
// })
// // 遍历关系
// this.links.forEach(link => {
//
// })
},
// 稀疏度
gSparsity () {
return (this.links.length / (this.nodes.length * Math.log(this.nodes.length))).toFixed(2)
}
},
watch: {
// 当请求到新的数据时,重新渲染
data (newData, oldData) {
console.log(newData, oldData)
// 移除svg和元素注册事件,防止内存泄漏
this.svgDom.on('.', null)
this.svgDom.selectAll('*').on('.', null)
this.d3init()
}
},
created () {
// this.states = Array(this.names.length).fill('on')
},
mounted () {
this.d3init()
},
beforeDestroy () {
// 移除svg和元素注册事件,防止内存泄漏
this.svgDom.on('.', null)
this.svgDom.selectAll('*').on('.', null)
},
methods: {
// 编辑当前选中节点
btnEdit () {
this.temp = Object.assign({}, this.selectNodeData.properties) // copy obj
this.dialogFormVisible = true
console.log(this.selectNodeData)
},
doEdit () {
// console.log(this.data)
let i = 0
// 更新props的data 和 selectNodeData
this.selectNodeData.name = this.temp.name
this.selectNodeData.properties = this.temp
for (let node of this.data.nodes) {
// console.log(node.id === this.selectNodeData.id)
// console.log(node.id)
// console.log(this.selectNodeData.id)
if (node.id == this.selectNodeData.id) {
// this.$set(this.data.nodes, i, this.selectNodeData)
// this.$set(this.nodes, i, this.selectNodeData)
this.data.nodes[i].properties = this.temp
this.nodes[i].properties = this.temp
break
}
i++
}
this.dialogFormVisible = false
this.d3init()
this.$message({
message: '更新成功',
type: 'success'
})
},
cancelEdit () {
this.dialogFormVisible = false
},
// 隐藏文字
changeTextState (state) {
// state发生变化时才进行更新、处理
if (this.textState !== state) {
this.textState = state
// const text = d3.selectAll('.texts text')
const text = d3.selectAll('.linkTexts text')
console.log(text)
// 根据新的节点状态,在节点上展示不同的文本信息
if (this.textState === 2) {
text.style('display', 'none')
// 暂不作校准
// // transform属性数值化
// // 原:translate(40, 8) scale(1)
// // 现:[40, 8, 1]
// let transform = d3.select('#svg1 g').attr('transform')
// transform = transform
// ? transform.match(/\d.?/g).map(item => parseInt(item))
// : [0, 0, 1]
// // 校准
// transform[0] = transform[0] + this.svgTranslate[0]
// transform[1] = transform[1] + this.svgTranslate[1]
// transform[2] = transform[2] * this.svgScale
// console.log(transform)
// // 隐藏节点后,svg自动缩放
// d3.select('#svg1 g').attr('transform', 'translate(' + transform[0] + ', ' + transform[1] + ') scale(' + transform[2] + ')')
} else {
text.style('display', 'block')
// 暂不作校准
// 显示节点后,svg自动还原
// d3.select('#svg1 g').attr('transform', '')
}
}
},
// 隐藏该类型的所有节点(图例)
hideNodeOfType (event) {
if (this.nodes.length === this.data.nodes.length
|| this.states.some((state) => state === 'off')) {
// console.log(event.target.dataset)
const index = event.target.dataset.index
const state = event.target.dataset.state
// const nodeTypes = ['Enterprise', 'Type', 'Region', 'Country']
// const linkTypes = ['', 'type', 'locate', 'export']
// 图例的状态切换(对应类型的节点隐藏)
if (state === 'on') {
// 隐藏该类型的所有节点及关联关系
// this.states[index] = 'off'
this.$set(this.states, index, 'off')
} else {
// this.states[index] = 'on'
this.$set(this.states, index, 'on')
}
/**************************************
* 状态更新后,同时对数据更新
*/
const indexs = this.states.map(s => {
if (s === 'on') {
return '1'
} else {
return '0'
}
})
// 遍历删除节点
this.nodes = this.data.nodes.filter(node => {
for (let i = 0; i < indexs.length; i++) {
if (node.label === this.labels[i] && indexs[i] === '0') return false
}
return true
})
// 遍历删除关系
this.links = this.data.links.filter(link => {
for (let i = 0; i < indexs.length; i++) {
if (i === 0 && indexs[i] === '0') return false
else if (link.type === this.linkTypes[i] && indexs[i] === '0') return false
}
return true
})
// 调试时使用
// console.log(indexs)
// console.log(this.data.nodes.length, this.data.links.length)
// console.log(this.nodes.length)
// console.log(this.links.length)
// 重新渲染
this.d3render()
} else {
this.$message.error('展示全部节点时才能隐藏图例')
}
},
/*eslint-disable*/
// 搜索包含关键字的节点
searchKeyWords (value) {
// 如果Input值是空的显示所有的圆和线(没有进行筛选)
if (this.keywords === '') {
this.clearGraphStyle()
}
// 否则判断判断三个元素是否等于name值,等于则显示该值
else {
var name = this.keywords
// 搜索所有的节点
this.svgDom.select('.nodes').selectAll('circle').attr('class', d => {
// 输入节点id的小写等于name则显示,否则隐藏
if (d.properties.name.indexOf(name) >= 0) {
return 'fixed'
} else {
// 优化:与该搜索节点相关联的节点均显示
// links链接的起始节点进行判断,如果其id等于name则显示这类节点
// 注意: graph=data
for (var i = 0; i < this.links.length; i++) {
// 如果links的起点等于name,并且终点等于正在处理的则显示
if ((this.links[i]['source'].properties.name.indexOf(name) >= 0) &&
(this.links[i]['target'].id == d.id)) {
return 'active'
}
// 如果links的终点等于name,并且起点等于正在处理的则显示
if ((this.links[i]['target'].properties.name.indexOf(name) >= 0) &&
(this.links[i]['source'].id == d.id)) {
return 'active'
}
}
return 'inactive' // 隐藏
}
})
// 搜索texts
this.svgDom.select('.texts').selectAll('text').attr('class', d => {
if (d.properties.name.indexOf(name) >= 0) {
return ''
} else {
// 优化:与该搜索节点相关联的节点均显示
// links链接的起始节点进行判断,如果其id等于name则显示这类节点
for (var i = 0; i < this.links.length; i++) {
// 如果links的起点等于name,并且终点等于正在处理的则显示
if ((this.links[i]['source'].properties.name.indexOf(name) >= 0) &&
(this.links[i]['target'].id == d.id)) {
return ''
}
//如果links的终点等于name,并且起点等于正在处理的则显示
if ((this.links[i]['target'].properties.name.indexOf(name) >= 0) &&
(this.links[i]['source'].id == d.id)) {
return ''
}
}
return 'inactive'
}
})
// 搜索links
// 显示相的邻边 注意 ||
this.svgDom.select(".links").selectAll('line').attr('class', d => {
if ((d.source.properties.name.indexOf(name) >= 0) ||
(d.target.properties.name.indexOf(name) >= 0)
) {
return ''
} else {
return 'inactive' //隐藏
}
})
// 搜索linkTexts
this.svgDom.select(".linkTexts").selectAll('text').attr('class', d => {
if ((d.source.properties.name.indexOf(name) >= 0) ||
(d.target.properties.name.indexOf(name) >= 0)
) {
return ''
} else {
return 'inactive' //隐藏
}
})
}
},
// d3初始化,包括数据解析、数据渲染
d3init () {
this.links = this.data.links
this.nodes = this.data.nodes
this.svgDom = d3.select('#svg') // 获取svg的DOM元素
// this.d3jsonParser(this.graph)
this.d3render()
// 数据状态初始化
this.stateInit()
},
// 数据状态初始化
stateInit () {
this.nodeState = 0
this.textState = 0
// console.log(this.names)
this.states = Array(this.names.length).fill('on')
},
d3render () {
var _this = this // 临时获取Vue实例,避免与d3的this指针冲突
// 渲染前清空svg内的元素
_this.svgDom.selectAll('*').remove()
// svg.selectAll('g').remove()
var svg = _this.svgDom
.on('click', () => {
// console.log(this.isNodeClicked)
this.isNodeClicked = false
// 移除所有样式
this.clearGraphStyle()
// 如果此时有搜索关键字,则鼠标离开时保留原搜索选中的节点
if(this.keywords !== '') {
this.searchKeyWords()
}
})
// 给画布绑定zoom事件(缩放、平移)
.call(d3.zoom().on('zoom', event => {
// console.log(event)
var scale = event.transform.k,
translate = [event.transform.x, event.transform.y]
// if (this.svgTranslate) {
// translate[0] += this.svgTranslate[0]
// translate[1] += this.svgTranslate[1]
// }
// if (this.svgScale) {
// scale *= this.svgScale
// }
svg.attr('transform', 'translate(' + translate[0] + ', ' + translate[1] + ') scale(' + scale + ')');
}))
.append('g')
.attr('width', '100%')
.attr('height', '100%')
this.addMarkers()
// console.log(svg)
// 动态变化时,不再固定宽高
// var width = svg.attr("width"),
// height = svg.attr("height")
// 解析json和数据处理
// 现在解析json直接在d3jsonParser()中更新nodes和links
// const data = this.d3jsonParser(this.graph)
// this.links = data.links.map(d => Object.create(d))
// this.nodes = data.nodes.map(d => Object.create(d))
// 定义碰撞检测模型
var forceCollide = d3.forceCollide()
.radius(d => { return 16 * 3 })
.iterations(0.15)
.strength(0.75)
// 利用d3.forceSimulation()定义关系图 包括设置边link、排斥电荷charge、关系图中心点
var simulation = d3.forceSimulation(this.nodes)
.force("link", d3.forceLink().id(d => d.id))
.force("charge", d3.forceManyBody().strength(-100))
// .force("center", d3.forceCenter(width / 2, height / 2)
.force("center", d3.forceCenter(svg.node().parentElement.clientWidth / 2, svg.node().parentElement.clientHeight / 2))
.force("collision", forceCollide)
// D3映射数据至HTML中
// g用于绘制所有边,selectALL选中所有的line,并绑定数据data(graph.links),enter().append("line")添加元素
// 数据驱动文档,设置边的粗细
var link = svg.append("g")
.attr("class", "links")
.selectAll("line")
.data(this.links).enter()
.append("line")
.attr("stroke-width", function(d) {
// 每次访问links的一项数据
return 2 //所有线宽度均为2
})
.join("path")
.attr("marker-end", "url(#posMarker)")
var linksName = svg.append("g")
.attr("class", "linkTexts")
.selectAll("text")
.data(this.links)
.join("text")
.style('text-anchor','middle')
.style('fill', '#fff')
.style('font-size', '12px')
// .style('font-weight', 'bold')
.text(d => d.properties.name)
// linksName
// .append('textPath')
// .attr('xlink:href', d => '#')
// .attr('startOffset', '50%')
// 添加所有的点
// selectAll("circle")选中所有的圆并绑定数据,圆的直径为d.size
// 再定义圆的填充色,同样数据驱动样式,圆没有描边,圆的名字为d.id
// call()函数:拖动函数,当拖动开始绑定dragstarted函数,拖动进行和拖动结束也绑定函数
var node = svg.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(this.nodes).enter()
.append("circle").attr("r", function(d) {
// 每次访问nodes的一项数据
// console.log(d)
let size = 16
switch(d.label){
case _this.labels[0]: break;
case _this.labels[1]: size = 14; break;
case _this.labels[2]: size = 13; break;
default: size = 13; break;
}
return size * 2
})
.attr("fill", d => {
for (let i = 0;i < this.labels.length;i++) {
if (d.label === this.labels[i]) return this.colors[i]
}
})
.attr("stroke", "none")
.attr("name", d => d.properties.name)
.attr("id", d => d.id)
.call(this.drag(simulation))
.on("click", nodeClick)
.on('mouseenter', function (event) {
// console.dir(this)
const node = d3.select(this)
// node.attr("class", "fixed")
// node.classed("fixed", true)
// console.log(node)
//获取被选中元素的名字
let name = node.attr("name")
let id = node.attr("id")
let color = node.attr('fill')
// console.log(name, id, color)
//设置#info h4样式的颜色为该节点的颜色,文本为该节点name
_this.$set(_this.selectNodeData, 'id', id)
_this.$set(_this.selectNodeData, 'name', name)
_this.$set(_this.selectNodeData, 'color', color)
//遍历查找id对应的属性
for (let item of _this.nodes) {
if (item.id == id) {
// for(var key in item.properties)
_this.$set(_this.selectNodeData, 'properties', item.properties)
}
}
// 遍历节点,并调整图的样式
_this.changeGraphStyle(name)
})
.on('mouseleave', event => {
console.log(this.isNodeClicked)
if (!this.isNodeClicked) {
this.clearGraphStyle()
// 如果此时有搜索关键字,则鼠标离开时保留原搜索选中的节点
if(this.keywords !== '') {
this.searchKeyWords()
}
}
})
.on('contextmenu', function(event, d) {
// 阻止默认右键菜单
event.preventDefault()
// 简单的控制台输出,替代完整的contextMenu功能
console.log('Node right-clicked:', d)
// 可以在这里添加简单的右键菜单逻辑
if (confirm('是否隐藏节点: ' + d.properties.name + '?')) {
// 隐藏节点的逻辑
_this.nodes = _this.nodes.filter(node => node.id !== d.id)
_this.links = _this.links.filter(link =>
link.source.id !== d.id && link.target.id !== d.id
)
_this.d3render()
}
})
// .on('contextmenu', function (d, i) {
// // 阻止默认右键菜单的弹出
// d3.event.preventDefault()
// })
// .call(d3.drag()
// .on("start", dragstarted)
// .on("drag", dragged)
// .on("end", dragended)
// )
// 显示所有的文本
// 设置大小、填充颜色、名字、text()设置文本
// 使用 attr("text-anchor", "middle")设置文本居中
var text = svg.append("g")
.attr("class", "texts")
.selectAll("text")
.data(this.nodes)
.enter()
.append("text").attr("font-size", () => 13)
.attr("fill", () => '#fff')
.attr('name', d => d.properties.name)
.attr("text-anchor", "middle")
.attr('x', function (d) {
return textBreaking(d3.select(this), d.properties.name)
})
.call(this.drag(simulation))
.on("click", nodeClick)
.on('mouseenter', function (event) {
// console.dir(this)
const text = d3.select(this)
// console.log(text)
// 获取被选中元素的名字
let name = text.attr("name")
_this.$set(_this.selectNodeData, 'name', name)
// 根据文本名称获取节点的id
for (let item of _this.nodes) {
if (item.properties.name == name) {
// 设置节点id和标签属性
_this.$set(_this.selectNodeData, 'id', item.id)
_this.$set(_this.selectNodeData, 'properties', item.properties)
// 根据节点类型label获取节点颜色
let index = 0
switch (item.label) {
case _this.labels[0]: break;
case _this.labels[1]: index = 1;break;
case _this.labels[2]: index = 2;break;
default: index = 3;break;
}
_this.$set(_this.selectNodeData, 'color', _this.colors[index])
}
}
_this.changeGraphStyle(name)
})
.on('mouseleave', (event) => {
if(!this.isNodeClicked) {
this.clearGraphStyle()
// 如果此时有搜索关键字,则鼠标离开时保留原搜索选中的节点
if(this.keywords !== '') {
this.searchKeyWords()
}
}
})
.on('contextmenu', function(event, d) {
// 阻止默认右键菜单
event.preventDefault()
// 简单的控制台输出
console.log('Text right-clicked:', d)
// 可以添加文本相关的右键逻辑
if (confirm('是否隐藏文本: ' + d.properties.name + '?')) {
// 隐藏对应节点的逻辑
_this.nodes = _this.nodes.filter(node => node.id !== d.id)
_this.links = _this.links.filter(link =>
link.source.id !== d.id && link.target.id !== d.id
)
_this.d3render()
}
})
// .call(d3.drag()
// .on("start", dragstarted)
// .on("drag", dragged)
// .on("end", dragended)
// )
// 圆增加title
node.append("title").text(d => d.properties.name)
// simulation中ticked数据初始化并生成图形
simulation.on("tick", ticked)
simulation.force("link")
.links(this.links)
.distance(d => { // 每一边的长度
let distance = 20
switch(d.source.label) {
case _this.labels[0]: distance += 30;break;
case _this.labels[1]: distance += 25;break;
case _this.labels[2]: distance += 22;break;
default: distance += 20;break;
}
switch(d.target.label) {
case _this.labels[0]: distance += 30;break;
case _this.labels[1]: distance += 25;break;
case _this.labels[2]: distance += 22;break;
default: distance += 20;break;
}
return distance * 2
})
/******************************************
* 内部功能函数
* 包括:ticked、文本分隔、节点和文本的点击事件
*/
// ticked()函数确定link线的起始点x、y坐标 node确定中心点 文本通过translate平移变化
function ticked() {
link
.attr("x1", d => d.source.x)
.attr("y1", d => d.source.y)
.attr("x2", d => d.target.x)
.attr("y2", d => d.target.y)
linksName
.attr('transform', d => {
let x = Math.min(d.source.x, d.target.x) + Math.abs(d.source.x - d.target.x) / 2
let y = Math.min(d.source.y, d.target.y) + Math.abs(d.source.y - d.target.y) / 2 - 1
// tanA = a / b
// A = arctan(tanA)
let tanA = Math.abs(d.source.y - d.target.y) / Math.abs(d.source.x - d.target.x)
let angle = Math.atan(tanA) / Math.PI * 180
// let angle = Math.atan2(1,1)/Math.PI*180
// console.log(angle)
// 第一、二象限额外处理
if (d.source.x > d.target.x) {
// 第二象限
if (d.source.y <= d.target.y) {
angle = -angle
}
// else { // 第三象限
// angle = angle
// }
} else if (d.source.y > d.target.y) {
// 第一象限
angle = -angle
}
return 'translate(' + x + ',' + y + ')' + 'rotate(' + angle + ')'
})
node
.attr("cx", d => d.x)
.attr("cy", d => d.y)
text.attr('transform', function(d) {
let size = 15
switch(d.label){
case _this.labels[0]: break;
case _this.labels[1]: size = 14;break;
case _this.labels[2]: size = 13;break;
default: size = 12;break;
}
size -= 5
return 'translate(' + (d.x - size / 2 + 3) + ',' + (d.y + size / 2) + ')'
})
}
/**
* 文本分隔(根据字数在当前选择器中分隔三行,超过10字省略)
* @method textBreaking
* @param {d3text} 文本对应的DOM对象
* @param {text} 节点名称的文本值
* @return {void}
*/
function textBreaking(d3text, text) {
const len = text.length
if (len <= 3) {
d3text.append('tspan')
.attr('x', 0)
.attr('y', 2)
.text(text)
} else {
const topText = text.substring(0, 3)
const midText = text.substring(3, 7)
let botText = text.substring(7, len)
let topY = -16
let midY = 0
let botY = 16
if (len <= 7) {
topY += 10
midY += 10
} else if (len > 10){
botText = text.substring(7, 9) + '...'
}
d3text.text('')
d3text.append('tspan')
.attr('x', 0)
.attr('y', topY)
.text(function () {
return topText
})
d3text.append('tspan')
.attr('x', 0)
.attr('y', midY)
.text(function () {
return midText
})
d3text.append('tspan')
.attr('x', 0)
.attr('y', botY)
.text(function () {
return botText
})
}
}
// 分别定义节点和文本的点击事件
// 优化:由于点击前必定触发mouseenter事件,所以不用再去查找节点id
// 直接根据this.selectNodeData拿到节点信息
// 优化后:只需定义一个点击事件即可
function nodeClick(event, d) {
// console.log('node clicked!')
// sticked用于固定节点(无法实现节点固定功能)
// delete d.fx
// delete d.fy
// d3.select(this).classed("fixed", true)
// simulation.alpha(1).restart()
// 获取被选中元素信息
// const node = d3.select(this)
// let name = node.attr("name")
// let id = node.attr("id")
// let color = node.attr('fill')
// console.log(name, id, color)
// 直接通过this.selectNodeData拿到节点信息
event.cancelBubble = true
event.stopPropagation() // 阻止事件冒泡
const name = _this.selectNodeData.name
_this.isNodeClicked = true
_this.changeGraphStyle(name)
return false
}
},
// 根据当前节点名称来更改图样式
changeGraphStyle (name) {
// console.log(this.isNodeClicked)
// 选择#svg1 .nodes中所有的circle,再增加个class
this.svgDom.select('.nodes').selectAll('circle').attr('class', d => {
// 节点属性name是否等于name,返回fixed(激活选中样式)
if(d.properties.name == name) {
return 'fixed'
}
// 当前节点返回空,否则其他节点循环判断是否被隐藏起来(CSS设置隐藏)
else {
// links链接的起始节点进行判断,如果其id等于name则显示这类节点
// 注意: graph = data
for (var i = 0; i < this.links.length; i++) {
// 如果links的起点等于name,并且终点等于正在处理的则显示
if (this.links[i]['source'].properties.name == name && this.links[i]['target'].id == d.id) {
return 'active'
}
if (this.links[i]['target'].properties.name == name && this.links[i]['source'].id == d.id) {
return 'active'
}
}
return this.isNodeClicked ? 'inactive' : ''
}
})
// 处理相邻的文字是否隐藏
this.svgDom.select('.texts').selectAll('text')
.attr('class', d => {
// 节点属性name是否等于name,返回fixed(激活选中样式)
if(d.properties.name == name) {
return ''
}
// 当前节点返回空,否则其他节点循环判断是否被隐藏起来(CSS设置隐藏)
else {
// links链接的起始节点进行判断,如果其id等于name则显示这类节点
// 注意: graph = data
for (var i = 0; i < this.links.length; i++) {
// 如果links的起点等于name,并且终点等于正在处理的则显示
if (this.links[i]['source'].properties.name == name && this.links[i]['target'].id == d.id) {
return ''
}
if (this.links[i]['target'].properties.name == name && this.links[i]['source'].id == d.id) {
return ''
}
}
return this.isNodeClicked ? 'inactive' : ''
}
})
// 处理相邻的边line是否隐藏 注意 ||
this.svgDom.select(".links").selectAll('line')
.attr('class', d => {
if (d.source.properties.name == name || d.target.properties.name == name) {
return 'active'
} else {
return this.isNodeClicked ? 'inactive' : ''
}
})
.attr('marker-end', d => {
if (d.source.properties.name == name || d.target.properties.name == name) {
return 'url(#posActMarker)'
} else {
return 'url(#posMarker)'
}
})
// 处理相邻的边上文字是否隐藏 注意 ||
this.svgDom.select(".linkTexts").selectAll('text')
.attr('class', d => {
if (d.source.properties.name == name || d.target.properties.name == name) {
return 'active'
} else {
return this.isNodeClicked ? 'inactive' : ''
}
})
},
clearGraphStyle () {
// 移除所有样式
this.svgDom.select('.nodes').selectAll('circle').attr('class', '')
this.svgDom.select(".texts").selectAll('text').attr('class', '')
this.svgDom.select('.links').selectAll('line').attr('class', '').attr('marker-end', 'url(#posMarker)')
this.svgDom.select(".linkTexts").selectAll('text').attr('class', '')
// d3.select(this).attr('class', '')
},
drag(simulation) {
function dragsubject(event) {
return simulation.find(event.x, event.y);
}
function dragstarted(event) {
if (!event.active) simulation.alphaTarget(0.3).restart();
event.subject.fx = event.subject.x;
event.subject.fy = event.subject.y;
}
function dragged(event) {
event.subject.fx = event.x;
event.subject.fy = event.y;
}
function dragended(event) {
if (!event.active) simulation.alphaTarget(0);
// 注释以下代码,使拖动结束后固定节点
// event.subject.fx = null;
// event.subject.fy = null;
}
return d3.drag()
.subject(dragsubject)
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended)
},
// 绘制关系箭头
addMarkers() {
// 定义箭头的标识
var defs = this.svgDom.append("defs")
const posMarker = defs.append("marker")
.attr("id", "posMarker")
.attr("orient", "auto")
.attr("stroke-width", 2)
.attr("markerUnits", "strokeWidth")
.attr("markerUnits", "userSpaceOnUse")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 31)
.attr("refY", 0)
.attr("markerWidth", 12)
.attr("markerHeight", 12)
.append("path")
.attr("d", "M 0 -5 L 10 0 L 0 5")
.attr('fill', '#e0cac1')
.attr("stroke-opacity", 0.6);
const posActMarker = defs.append("marker")
.attr("id", "posActMarker")
.attr("orient", "auto")
.attr("stroke-width", 2)
.attr("markerUnits", "strokeWidth")
.attr("markerUnits", "userSpaceOnUse")
.attr("viewBox", "0 -5 10 10")
.attr("refX", 31)
.attr("refY", 0)
.attr("markerWidth", 12)
.attr("markerHeight", 12)
.append("path")
.attr("d", "M 0 -5 L 10 0 L 0 5")
.attr('fill', '#1E90FF')
.attr("stroke-opacity", 0.6);
// const negMarker = defs.append("marker")
// .attr("id","negMarker")
// .attr("orient","auto")
// .attr("stroke-width",2)
// .attr("markerUnits", "strokeWidth")
// .attr("markerUnits", "userSpaceOnUse")
// .attr("viewBox", "0 -5 10 10")
// .attr("refX", -25)
// .attr("refY", 0)
// .attr("markerWidth", 12)
// .attr("markerHeight", 12)
// .append("path")
// .attr("d", "M 10 -5 L 0 0 L 10 5")
// .attr('fill', '#999')
// .attr("stroke-opacity", 0.6);
}
}
}
</script>
<style lang="scss">
@import '../plugins/d3-context-menu';
$opacity: 0.15; /* 显示的不透明度 */
$activeColor: #1E90FF; /* 激活的颜色 */
svg {
margin: 20px 0px;
// border: 1px #000 solid;
overflow: hidden;
}
/*设置节点及边的样式*/
.links line {
stroke: #e0cac1b2; // #bbb
stroke-opacity: 1;
&.inactive {
/* display: none !important; */
opacity: $opacity;
}
&.active {
stroke: $activeColor;
stroke-width: 3px;
}
&.hide {
display: none !important;
}
}
.nodes circle {
// stroke: #000;
// stroke-width: 1.5px;
&.fixed {
// fill: rgb(102, 81, 81);
stroke: #FFC0CB; // #888;
stroke-width: 14px;
stroke-opacity: $opacity + 0.3;
border: 10px #000 solid;
}
&.inactive {
/* display: none !important; */
opacity: $opacity;
}
&.active {
stroke: $activeColor;
stroke-width: 4px;
}
&:hover {
cursor: pointer;
}
&.hide {
display: none !important;
}
}
.texts text {
cursor: pointer;
text-decoration: none;
user-select: none;
&:hover {
cursor: pointer;
}
&.inactive {
/* display: none !important; */
opacity: $opacity;
}
}
.linkTexts text {
stroke: #ecddd8b2; // #bbb
stroke-opacity: 1;
&.active {
stroke: $activeColor;
}
&.inactive {
/* display: none !important; */
opacity: $opacity;
}
}
// #positiveMarker path {
// fill: #fff;
// }
</style>
<style lang="scss" scoped>
@media only screen and (max-width: 1125px){
#info, #mode {
display: none !important;
}
}
.font-sky {
font-size: 18px;
color: #034c6a !important;
}
#indicator {
position: absolute;
// left: 50px;
// bottom: 30px;
left: 3vw;
bottom: 12vw;
text-align: left;
color: #f2f2f2;
font-size: 14px;
font-weight: bold;
& > div {
margin-bottom: 4px;
}
span {
display: inline-block;
width: 32px;
height: 16px;
position: relative;
top: 2px;
margin-right: 8px;
}
}
/*mode选项样式*/
#mode {
position: absolute;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
top: 200px;
left: 40px;
.gState span {
display: inline-block;
border: 1px solid #fff;
color: #fff;
padding: 6px 10px;
border-radius: 4px;
font-size: 14px;
transition: color, background-color .3s;
-o-transition: color, background-color .3s;
-ms-transition: color, background-color .3s;
-moz-transition: color, background-color .3s;
-webkit-transition: color, background-color .3s;
~ .active, ~ :hover {
background-color: #fff;
color: #333;
cursor: pointer;
}
}
.gState span.active, .gState span:hover {
background-color: #fff;
color: #333;
cursor: pointer;
}
}
/*悬浮节点的info样式*/
#info {
position: absolute;
bottom: 40px;
right: 30px;
width: 270px;
.node-card {
border: 1px solid #9faecf;
background-color: #00aeff6b;
color: #fff;
text-align: left;
// transition: background-color;
// transition-delay: .3s;
// transition-timing-function: ease;
.el-card__header {
border-bottom: 1px solid #50596d;
}
}
}
</style>
<template>
<div class="lineContainer">
<svg width="500" height="270">
<g style="transform: translate(0, 10px)">
<path :d="line" />
</g>
</svg>
</div>
</template>
<script>
export default {
name: 'd3line',
data() {
return {
data: [99, 71, 78, 25, 36, 92],
line: '',
};
},
mounted() {
this.calculatePath();
},
methods: {
getScales() {
const x = d3.scaleTime().range([0, 430]);
const y = d3.scaleLinear().range([210, 0]);
d3.axisLeft().scale(x);
d3.axisBottom().scale(y);
x.domain(d3.extent(this.data, (d, i) => i));
y.domain([0, d3.max(this.data, d => d)]);
return { x, y };
},
calculatePath() {
const scale = this.getScales();
const path = d3.line()
.x((d, i) => scale.x(i))
.y(d => scale.y(d));
this.line = path(this.data);
},
},
}
</script>
<style lang="scss" scoped>
.lineContainer {
position: relative;
border: 2px #000 solid;
background-color: #9dadc1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
svg {
margin: 25px;
path {
fill: none;
stroke: #76BF8A;
stroke-width: 3px;
}
}
}
</style>
\ No newline at end of file
<template>
<div style="margin-top: 20px;width: 500px;">
<!-- <el-button style="margin-top: 15px;" @click="query">图数据切换,动态更新</el-button> -->
<el-autocomplete
style="width: 500px"
class="inline-input"
v-model="input"
:fetch-suggestions="querySearch"
placeholder="请输入内容"
:trigger-on-focus="false"
@select="handleSelect"
clearable
>
<!-- <el-select
v-model="mode"
slot="prepend"
placeholder="关键字查询"
>
<el-option label="关键字查询" value="1"></el-option>
<el-option label="单实体查询" value="2"></el-option>
<el-option label="关联查询" value="3"></el-option>
</el-select> -->
<el-button
slot="append"
type="success"
icon="el-icon-search"
@click="query"
>搜索</el-button>
</el-autocomplete>
</div>
</template>
<script>
// 导入JSON数据
import recordsData from '../data/records.json'
import top5Data from '../data/top5.json'
export default {
name: 'gSearch',
// props: {
// isShowPrepend: {
// type: Boolean,
// default: true
// }
// },
data () {
return {
input: '',
mode: '1',
// 后台请求到的json数据
data: recordsData,
results: []
}
},
mounted () {
this.$emit('getData', this.data)
this.results = this.loadAll()
},
methods: {
query () {
// console.log(typeof this.mode)
if (this.data.length <= 20) {
this.data = top5Data
} else {
this.data = recordsData
}
this.$emit('getData', this.data)
},
querySearch (queryString, cb) {
var res = this.results
var results = queryString ? res.filter(this.createFilter(queryString)) : res
// 调用 callback 返回建议列表的数据
cb(results)
},
createFilter (queryString) {
return (res) => {
return (res.value.toLowerCase().indexOf(queryString.toLowerCase()) !== -1)
}
},
// 模拟加载数据
loadAll () {
return [
{ value: '浙江鹏顺进出口有限公司', address: '浙江诸暨艮塔路9号银证大厦8楼' },
{ value: '玉环达丰环保设备有限公司', address: '玉环市芦浦镇漩门工业城' },
{ value: '宁波海天精工股份有限公司', address: '宁波市北仑区黄山西路235号' },
{ value: '象山东兴雕刻古董家具有限公司', address: '城西路4号' },
{ value: '绍兴千海进出口有限公司', address: '绍兴袍江启圣路以南与越英路交叉口生产车间' },
{ value: '深圳万测进出口有限公司', address: '深圳' }
]
},
handleSelect (item) {
console.log(item)
}
}
}
</script>
<style lang='scss' scoped>
.el-select {
width: 120px;
// background-color: #fff;
}
.input-with-select .el-input-group__prepend {
background-color: #6ecbf3;
}
</style>
<template>
<div>
<div id="3d-graph" class="three-graph"></div>
<!-- 绘制图例 -->
<div id="indicator">
<!-- 利用item 遍历一个数组 利用index 遍历另外一个数组 -->
<div v-for="(name, index) in names" :key="index">
<span
:data-state="states[index]"
:data-index="index"
:style="{ backgroundColor: states[index] === 'on' ? nodeColors[index] : '#aaa' }"
></span>
{{ name }}
</div>
</div>
<!-- 绘制右边显示结果 -->
<div id="info" v-show="selectNodeData.name !== undefined">
<!-- <h4 :style="{ color: selectNodeData.color }">{{ selectNodeData.name }}</h4>
<p v-for="(item, key) in selectNodeData.properties" :key="item">
<span>{{ key }}</span>
{{ item }}
</p> -->
<el-card
:style="{ backgroundColor: selectNodeData.color }"
class="node-card"
>
<div slot="header" class="clearfix">
<span>{{ selectNodeData.name }}</span>
<el-button
@click="btnEdit"
style="float: right; padding: 3px 0;color: #409EFB;font-size: 15px;"
type="text"
>编辑</el-button>
</div>
<div
v-for="(item, key) in selectNodeData.properties" :key="item"
>
<span style="margin-right: 8px;">{{ (nodeObjMap[key] ? nodeObjMap[key] : key) + ':' }}</span>
<span style="text-align: right;"><b>{{ item }}</b></span>
</div>
</el-card>
</div>
<!-- 编辑框 -->
<el-dialog :visible.sync="dialogFormVisible">
<el-form
:model="temp"
label-position="right"
label-width="86px"
style="width: 500px; margin-left:50px;"
>
<el-form-item
v-for="(value, key) in temp"
:key="key"
:label="nodeObjMap[key] ? nodeObjMap[key] : key"
>
<el-input
v-model="temp[key]"
:readonly="!isEdit"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelEdit">
取消
</el-button>
<el-button type="primary" @click="doEdit">
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import ForceGraph3D from '3d-force-graph'
// threejs的精灵标签,用于文字的展示
import SpriteText from 'three-spritetext'
export default {
name: 'threeGraph',
props: {
data: {
type: Object,
default: function () {
return {
nodes: [],
links: []
}
}
},
/* eslint-disable */
// 自定义图例(数组保证一一对应)
// names 图例名称变量制作图标
// labels 节点的标签名称(与records.json中保证相同)
names: {
type: Array
},
labels: Array,
linkTypes: Array
},
mounted () {
this.threeInit()
},
data () {
return {
// ForceGraph3D对象,供全局调用,实现动态更新
Graph: {},
// threeRender()最终展示到页面上的数据(节点隐藏功能)
nodes: [],
links: [],
// 图例的名称、对应的颜色以及图例状态
states: [],
nodeColors: ['#55cccc', '#aaaaff', '#4e88af', '#ca635f','#FFC0CB', '#BA55D3', '#1E90FF', '#7FFFD4','#FFFF00'],
selectNodeData: {}, // 选中节点的详细信息展示
temp: {}, // 临时存储编辑时的节点信息
dialogFormVisible: false,
isEdit: true,
// 节点属性对应的标签名称
nodeObjMap: {
'address': '注册地址',
'captial': '注册资本',
'credit_code': '信用代码',
'name': '节点名称',
'setup_time': '注册日期'
}
}
},
watch: {
// 当请求到新的数据时,重新渲染
data (newData, oldData) {
console.log(newData, oldData)
this.threeInit()
}
},
methods: {
// 视图更新
update () {
if (this.graph.length <= 20) {
this.graph = require('../data/top5.json')
} else {
this.graph = require('../data/records.json')
}
// console.log(this.graph)
console.log(this.graph.length)
this.neoJsonParser(this.graph)
// console.log(this.Graph)
// 更新前清空DOM内canvas元素
// 注意固定容器的宽高,防止渲染时容器塌陷
document.getElementById('3d-graph').innerHTML = ''
this.threeRender()
// 更新数据暂不能用,卡死
// this.threeUpdate({
// nodes: [],
// links: []
// })
},
// 编辑当前选中节点
btnEdit () {
this.temp = Object.assign({}, this.selectNodeData.properties) // copy obj
this.dialogFormVisible = true
console.log(this.selectNodeData)
},
doEdit () {
// console.log(this.data)
let i = 0
// 更新props的data 和 selectNodeData
this.selectNodeData.name = this.temp.name
this.selectNodeData.properties = this.temp
for (let node of this.data.nodes) {
// console.log(node.id === this.selectNodeData.id)
// console.log(node.id)
// console.log(this.selectNodeData.id)
if (node.id == this.selectNodeData.id) {
// this.$set(this.data.nodes, i, this.selectNodeData)
// this.$set(this.nodes, i, this.selectNodeData)
this.data.nodes[i].properties = this.temp
this.nodes[i].properties = this.temp
break
}
i++
}
this.dialogFormVisible = false
this.threeInit()
this.$message({
message: '更新成功',
type: 'success'
})
},
cancelEdit () {
this.dialogFormVisible = false
},
// d3初始化,包括数据解析、数据渲染
threeInit () {
this.links = this.data.links
this.nodes = this.data.nodes
this.threeRender()
// 数据状态初始化
this.stateInit()
},
// 数据状态初始化
stateInit () {
this.states = Array(this.names.length).fill('on')
},
threeRender () {
// DOM初始化及数据挂载
const elm = document.getElementById('3d-graph')
this.Graph = ForceGraph3D()(elm)
.graphData(this.data)
// 设置画布样式、节点及关系样式、事件绑定等
this.Graph.height(750).width(1200)
.backgroundColor('#9dadc1')
// 节点样式和标签设置
.nodeRelSize(7)
.nodeColor(node => {
let index = 0
switch(node.label) {
case this.labels[0]: break;
case this.labels[1]: index = 1;break;
case this.labels[2]: index = 2;break;
default: index = 3;break;
}
return this.nodeColors[index]
})
// .nodeAutoColorBy('label')
// 给节点添加文字
// .nodeThreeObjectExtend(true)
.nodeThreeObject(node => {
const sprite = new SpriteText(node.properties.name)
sprite.material.depthWrite = false // make sprite background transparent
// 设置文字颜色
let i = 0
// switch(node.label) {
// case this.labels[0]: break;
// case this.labels[1]: index = 1;break;
// case this.labels[2]: index = 2;break;
// default: index = 3;break;
// }
for (;i < this.labels.length;i++) {
if (node.label === this.labels[i]) break
}
sprite.color = this.nodeColors[i]
sprite.textHeight = 8
return sprite
})
.nodeThreeObjectExtend(true)
.nodeLabel(node => `${node.label}: ${node.properties.name}`)
.nodeOpacity(0.75)
// 节点事件绑定
.onNodeHover(node => elm.style.cursor = node ? 'pointer' : null)
.onNodeClick(node => {
console.log(node)
//设置#info h4样式的颜色为该节点的颜色,文本为该节点name
this.$set(this.selectNodeData, 'id', node.id)
this.$set(this.selectNodeData, 'name', node.properties.name)
// 获取节点类型对应的颜色
// let index = 0
// switch(node.label) {
// case 'Enterprise': break;
// case 'Type': index = 1;break;
// case 'Region': index = 2;break;
// default: index = 3;break;
// }
let i = 0
for (;i < this.labels.length;i++) {
if (node.label === this.labels[i]) break
}
this.$set(this.selectNodeData, 'color', this.nodeColors[i])
this.$set(this.selectNodeData, 'properties', node.properties)
})
// 关系样式
// .linkColor('#bbb')
// .linkColor(link => {
// let index = 0
// const colors = ['#faa']
// switch(link.type) {
// case 'export': break;
// case 'type': index = 1;break;
// case 'locate': index = 2;break;
// default: index = 3;break;
// }
// return this.nodeColors[index]
// })
// .linkOpacity(1)
// Spread nodes a little wider
this.Graph.d3Force('charge').strength(-150)
},
threeUpdate (data) {
this.Graph.graphData({
data
})
},
// 随机生成一个规模为N的图
createRandomGraph (N = 300) {
return {
nodes: [...Array(N).keys()].map(i => ({ id: i })),
links: [...Array(N).keys()]
.filter(id => id)
.map(id => ({
source: id,
target: Math.round(Math.random() * (id - 1))
}))
}
}
},
}
</script>
<style lang="scss" scoped>
@media only screen and (max-width: 1200px){
#info, #indicator {
display: none !important;
}
}
.three-graph {
width: 1200px;
height: 750px;
// background-color: #000;
margin: 20px 0px;
// border: 2px #fff solid;
overflow: hidden;
}
#indicator {
position: absolute;
// left: 50px;
// bottom: 30px;
left: 3vw;
bottom: 12vw;
text-align: left;
color: #f2f2f2;
font-size: 14px;
font-weight: bold;
& > div {
margin-bottom: 4px;
}
span {
display: inline-block;
width: 32px;
height: 16px;
position: relative;
top: 2px;
margin-right: 8px;
}
}
/*悬浮节点的info样式*/
/*悬浮节点的info样式*/
#info {
position: absolute;
bottom: 40px;
right: 30px;
width: 270px;
.node-card {
border: 1px solid #9faecf;
background-color: #00aeff6b;
color: #fff;
text-align: left;
// transition: background-color;
// transition-delay: .3s;
// transition-timing-function: ease;
.el-card__header {
border-bottom: 1px solid #50596d;
}
}
}
// #info {
// position: absolute;
// bottom: 40px;
// right: 30px;
// text-align: right;
// width: 270px;
// p {
// color: #fff;
// font-size: 12px;
// margin-top: 0;
// margin-bottom: 5px;
// }
// p span {
// color: #888;
// margin-right: 10px;
// }
// h4 {
// color: #fff;
// }
// }
</style>
[
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 626262,
"start": 0,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120895,
"labels": [
"Country"
],
"properties": {
"name": "委内瑞拉"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 582838,
"start": 0,
"end": 120895,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120895,
"labels": [
"Country"
],
"properties": {
"name": "委内瑞拉"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120934,
"labels": [
"Country"
],
"properties": {
"name": "德国"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 553108,
"start": 0,
"end": 120934,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120934,
"labels": [
"Country"
],
"properties": {
"name": "德国"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 551319,
"start": 0,
"end": 120810,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120811,
"labels": [
"Country"
],
"properties": {
"name": "古巴"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 544129,
"start": 0,
"end": 120811,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120811,
"labels": [
"Country"
],
"properties": {
"name": "古巴"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120888,
"labels": [
"Country"
],
"properties": {
"name": "秘鲁"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 536963,
"start": 0,
"end": 120888,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120888,
"labels": [
"Country"
],
"properties": {
"name": "秘鲁"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120969,
"labels": [
"Country"
],
"properties": {
"name": "洪都拉斯"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 452313,
"start": 0,
"end": 120969,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120969,
"labels": [
"Country"
],
"properties": {
"name": "洪都拉斯"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120805,
"labels": [
"Country"
],
"properties": {
"name": "玻利维亚"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 433083,
"start": 0,
"end": 120805,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120805,
"labels": [
"Country"
],
"properties": {
"name": "玻利维亚"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120931,
"labels": [
"Country"
],
"properties": {
"name": "赞比亚"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 287699,
"start": 0,
"end": 120931,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120931,
"labels": [
"Country"
],
"properties": {
"name": "赞比亚"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120926,
"labels": [
"Country"
],
"properties": {
"name": "美国"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 215520,
"start": 0,
"end": 120926,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120926,
"labels": [
"Country"
],
"properties": {
"name": "美国"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120979,
"labels": [
"Country"
],
"properties": {
"name": "肯尼亚"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 207691,
"start": 0,
"end": 120979,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120979,
"labels": [
"Country"
],
"properties": {
"name": "肯尼亚"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 121034,
"labels": [
"Country"
],
"properties": {
"name": "安哥拉"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 155265,
"start": 0,
"end": 121034,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 121034,
"labels": [
"Country"
],
"properties": {
"name": "安哥拉"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120880,
"labels": [
"Country"
],
"properties": {
"name": "马来西亚"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 98740,
"start": 0,
"end": 120880,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120880,
"labels": [
"Country"
],
"properties": {
"name": "马来西亚"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120913,
"labels": [
"Country"
],
"properties": {
"name": "伊朗"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 96972,
"start": 0,
"end": 120913,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120913,
"labels": [
"Country"
],
"properties": {
"name": "伊朗"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120954,
"labels": [
"Country"
],
"properties": {
"name": "加蓬"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 87265,
"start": 0,
"end": 120954,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120954,
"labels": [
"Country"
],
"properties": {
"name": "加蓬"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"end": {
"identity": 120850,
"labels": [
"Region"
],
"properties": {
"name": "北京"
}
},
"segments": [
{
"start": {
"identity": 0,
"labels": [
"Enterprise"
],
"properties": {
"name": "中国航空技术北京有限公司",
"setup_time": "1988/8/12",
"address": "北京市北京经济技术开发区宏达北路16号6号楼",
"captial": "80000.0万人民币",
"credit_code": "91110302101114816L"
}
},
"relationship": {
"identity": 22591,
"start": 0,
"end": 120850,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120850,
"labels": [
"Region"
],
"properties": {
"name": "北京"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 1,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州市沃尔夫国际贸易有限公司",
"setup_time": "2006/8/23",
"address": "台州市黄岩春江苑1-1-1902室",
"captial": "56.0万人民币",
"credit_code": "91331003789652240P"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 1,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州市沃尔夫国际贸易有限公司",
"setup_time": "2006/8/23",
"address": "台州市黄岩春江苑1-1-1902室",
"captial": "56.0万人民币",
"credit_code": "91331003789652240P"
}
},
"relationship": {
"identity": 700058,
"start": 1,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 1,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州市沃尔夫国际贸易有限公司",
"setup_time": "2006/8/23",
"address": "台州市黄岩春江苑1-1-1902室",
"captial": "56.0万人民币",
"credit_code": "91331003789652240P"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
},
"segments": [
{
"start": {
"identity": 1,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州市沃尔夫国际贸易有限公司",
"setup_time": "2006/8/23",
"address": "台州市黄岩春江苑1-1-1902室",
"captial": "56.0万人民币",
"credit_code": "91331003789652240P"
}
},
"relationship": {
"identity": 336736,
"start": 1,
"end": 120810,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 1,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州市沃尔夫国际贸易有限公司",
"setup_time": "2006/8/23",
"address": "台州市黄岩春江苑1-1-1902室",
"captial": "56.0万人民币",
"credit_code": "91331003789652240P"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
},
"segments": [
{
"start": {
"identity": 1,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州市沃尔夫国际贸易有限公司",
"setup_time": "2006/8/23",
"address": "台州市黄岩春江苑1-1-1902室",
"captial": "56.0万人民币",
"credit_code": "91331003789652240P"
}
},
"relationship": {
"identity": 5787,
"start": 1,
"end": 120861,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 2,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州宏汇机械有限公司",
"setup_time": "2007/1/11",
"address": "玉环县汽摩工业园金汇路6号",
"captial": "777.0万人民币",
"credit_code": "91331021757055863T"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 2,
"labels": [
"Enterprise"
],
"properties": {
"name": "台州宏汇机械有限公司",
"setup_time": "2007/1/11",
"address": "玉环县汽摩工业园金汇路6号",
"captial": "777.0万人民币",
"credit_code": "91331021757055863T"
}
},
"relationship": {
"identity": 705442,
"start": 2,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
}
}
]
\ No newline at end of file
[
{
"p": {
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"relationship": {
"identity": 683943,
"start": 28,
"end": 122723,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122723,
"labels": [
"Type"
],
"properties": {
"name": "生产型"
}
}
},
{
"start": {
"identity": 122723,
"labels": [
"Type"
],
"properties": {
"name": "生产型"
}
},
"relationship": {
"identity": 620306,
"start": 46,
"end": 122723,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"relationship": {
"identity": 526049,
"start": 28,
"end": 120786,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
}
},
{
"start": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
},
"relationship": {
"identity": 504363,
"start": 46,
"end": 120786,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"relationship": {
"identity": 446386,
"start": 28,
"end": 120976,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120976,
"labels": [
"Country"
],
"properties": {
"name": "阿富汗"
}
}
},
{
"start": {
"identity": 120976,
"labels": [
"Country"
],
"properties": {
"name": "阿富汗"
}
},
"relationship": {
"identity": 380370,
"start": 46,
"end": 120976,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"relationship": {
"identity": 224315,
"start": 28,
"end": 120919,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120919,
"labels": [
"Country"
],
"properties": {
"name": "卡塔尔"
}
}
},
{
"start": {
"identity": 120919,
"labels": [
"Country"
],
"properties": {
"name": "卡塔尔"
}
},
"relationship": {
"identity": 277377,
"start": 46,
"end": 120919,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 28,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市葆丰医疗器械有限公司",
"setup_time": "2009/9/27",
"address": "深圳市龙岗区南湾街道吉厦早禾坑工业区3号C栋厂房一楼",
"captial": "50.0万人民币",
"credit_code": "91440300695579070F"
}
},
"relationship": {
"identity": 19068,
"start": 28,
"end": 120853,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120853,
"labels": [
"Region"
],
"properties": {
"name": "广东省"
}
}
},
{
"start": {
"identity": 120853,
"labels": [
"Region"
],
"properties": {
"name": "广东省"
}
},
"relationship": {
"identity": 32064,
"start": 46,
"end": 120853,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"relationship": {
"identity": 711801,
"start": 25,
"end": 122723,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122723,
"labels": [
"Type"
],
"properties": {
"name": "生产型"
}
}
},
{
"start": {
"identity": 122723,
"labels": [
"Type"
],
"properties": {
"name": "生产型"
}
},
"relationship": {
"identity": 620306,
"start": 46,
"end": 122723,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"relationship": {
"identity": 154652,
"start": 25,
"end": 120916,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120916,
"labels": [
"Country"
],
"properties": {
"name": "斯里兰卡"
}
}
},
{
"start": {
"identity": 120916,
"labels": [
"Country"
],
"properties": {
"name": "斯里兰卡"
}
},
"relationship": {
"identity": 532199,
"start": 46,
"end": 120916,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"relationship": {
"identity": 191779,
"start": 25,
"end": 120786,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
}
},
{
"start": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
},
"relationship": {
"identity": 504363,
"start": 46,
"end": 120786,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"relationship": {
"identity": 442315,
"start": 25,
"end": 120880,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120880,
"labels": [
"Country"
],
"properties": {
"name": "马来西亚"
}
}
},
{
"start": {
"identity": 120880,
"labels": [
"Country"
],
"properties": {
"name": "马来西亚"
}
},
"relationship": {
"identity": 311756,
"start": 46,
"end": 120880,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"segments": [
{
"start": {
"identity": 25,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市中微泽电子有限公司",
"setup_time": "2000/2/21",
"address": "深圳市龙岗区布吉街道赛格新城市广场第五号楼一座17层1703房",
"captial": "1250.0万人民币",
"credit_code": "91440300715274566C"
}
},
"relationship": {
"identity": 63811,
"start": 25,
"end": 120853,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120853,
"labels": [
"Region"
],
"properties": {
"name": "广东省"
}
}
},
{
"start": {
"identity": 120853,
"labels": [
"Region"
],
"properties": {
"name": "广东省"
}
},
"relationship": {
"identity": 32064,
"start": 46,
"end": 120853,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
}
}
],
"length": 2.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 122723,
"labels": [
"Type"
],
"properties": {
"name": "生产型"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 620306,
"start": 46,
"end": 122723,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122723,
"labels": [
"Type"
],
"properties": {
"name": "生产型"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 121018,
"labels": [
"Country"
],
"properties": {
"name": "中国香港"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 534438,
"start": 46,
"end": 121018,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 121018,
"labels": [
"Country"
],
"properties": {
"name": "中国香港"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120916,
"labels": [
"Country"
],
"properties": {
"name": "斯里兰卡"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 532199,
"start": 46,
"end": 120916,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120916,
"labels": [
"Country"
],
"properties": {
"name": "斯里兰卡"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 504363,
"start": 46,
"end": 120786,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120802,
"labels": [
"Country"
],
"properties": {
"name": "阿联酋"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 484125,
"start": 46,
"end": 120802,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120802,
"labels": [
"Country"
],
"properties": {
"name": "阿联酋"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120978,
"labels": [
"Country"
],
"properties": {
"name": "伊拉克"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 475425,
"start": 46,
"end": 120978,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120978,
"labels": [
"Country"
],
"properties": {
"name": "伊拉克"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120976,
"labels": [
"Country"
],
"properties": {
"name": "阿富汗"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 380370,
"start": 46,
"end": 120976,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120976,
"labels": [
"Country"
],
"properties": {
"name": "阿富汗"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120880,
"labels": [
"Country"
],
"properties": {
"name": "马来西亚"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 311756,
"start": 46,
"end": 120880,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120880,
"labels": [
"Country"
],
"properties": {
"name": "马来西亚"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120919,
"labels": [
"Country"
],
"properties": {
"name": "卡塔尔"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 277377,
"start": 46,
"end": 120919,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120919,
"labels": [
"Country"
],
"properties": {
"name": "卡塔尔"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120893,
"labels": [
"Country"
],
"properties": {
"name": "科威特"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 244652,
"start": 46,
"end": 120893,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120893,
"labels": [
"Country"
],
"properties": {
"name": "科威特"
}
}
}
],
"length": 1.0
}
},
{
"p": {
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"end": {
"identity": 120853,
"labels": [
"Region"
],
"properties": {
"name": "广东省"
}
},
"segments": [
{
"start": {
"identity": 46,
"labels": [
"Enterprise"
],
"properties": {
"name": "深圳市鑫立达宏科技有限公司",
"setup_time": "2005/7/13",
"address": "深圳市龙华区福城街道茜坑社区观澜大道19号23栋603",
"captial": "100.0万人民币",
"credit_code": "91440300777175432L"
}
},
"relationship": {
"identity": 32064,
"start": 46,
"end": 120853,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120853,
"labels": [
"Region"
],
"properties": {
"name": "广东省"
}
}
}
],
"length": 1.0
}
}
]
\ No newline at end of file
[
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 621275,
"start": 110531,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
}
]
\ No newline at end of file
[
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 621275,
"start": 110531,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 572542,
"start": 110531,
"end": 120807,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 120959,
"labels": [
"Country"
],
"properties": {
"name": "乌兹别克斯坦"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 483409,
"start": 110531,
"end": 120959,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120959,
"labels": [
"Country"
],
"properties": {
"name": "乌兹别克斯坦"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 120911,
"labels": [
"Country"
],
"properties": {
"name": "乌克兰"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 448692,
"start": 110531,
"end": 120911,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120911,
"labels": [
"Country"
],
"properties": {
"name": "乌克兰"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 381870,
"start": 110531,
"end": 120810,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 272148,
"start": 110531,
"end": 120965,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 237492,
"start": 110531,
"end": 120786,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
},
"segments": [
{
"start": {
"identity": 110531,
"labels": [
"Enterprise"
],
"properties": {
"name": "浙江鹏顺进出口有限公司",
"setup_time": "2007/5/17",
"address": "浙江诸暨艮塔路9号银证大厦8楼",
"captial": "0万人民币",
"credit_code": "3306812004868"
}
},
"relationship": {
"identity": 14691,
"start": 110531,
"end": 120861,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
}
}
],
"length": 1.0
},
"score": 2.307142857142857
},
{
"p": {
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"relationship": {
"identity": 727151,
"start": 46429,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
},
"score": 2.275
},
{
"p": {
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"end": {
"identity": 120996,
"labels": [
"Country"
],
"properties": {
"name": "墨西哥"
}
},
"segments": [
{
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"relationship": {
"identity": 596245,
"start": 46429,
"end": 120996,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120996,
"labels": [
"Country"
],
"properties": {
"name": "墨西哥"
}
}
}
],
"length": 1.0
},
"score": 2.275
},
{
"p": {
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
},
"segments": [
{
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"relationship": {
"identity": 486085,
"start": 46429,
"end": 120965,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
}
}
],
"length": 1.0
},
"score": 2.275
},
{
"p": {
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"end": {
"identity": 120911,
"labels": [
"Country"
],
"properties": {
"name": "乌克兰"
}
},
"segments": [
{
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"relationship": {
"identity": 471462,
"start": 46429,
"end": 120911,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120911,
"labels": [
"Country"
],
"properties": {
"name": "乌克兰"
}
}
}
],
"length": 1.0
},
"score": 2.275
},
{
"p": {
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
},
"segments": [
{
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"relationship": {
"identity": 411461,
"start": 46429,
"end": 120807,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
}
}
],
"length": 1.0
},
"score": 2.275
},
{
"p": {
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
},
"segments": [
{
"start": {
"identity": 46429,
"labels": [
"Enterprise"
],
"properties": {
"name": "象山东兴雕刻古董家具有限公司(2002)",
"setup_time": "1900/1/1",
"address": "城西路4号",
"captial": "0万人民币",
"credit_code": "3302251001312"
}
},
"relationship": {
"identity": 29583,
"start": 46429,
"end": 120861,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
}
}
],
"length": 1.0
},
"score": 2.275
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 716536,
"start": 55345,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120925,
"labels": [
"Country"
],
"properties": {
"name": "西班牙"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 328349,
"start": 55345,
"end": 120925,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120925,
"labels": [
"Country"
],
"properties": {
"name": "西班牙"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120796,
"labels": [
"Country"
],
"properties": {
"name": "法国"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 302917,
"start": 55345,
"end": 120796,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120796,
"labels": [
"Country"
],
"properties": {
"name": "法国"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 215167,
"start": 55345,
"end": 120810,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120802,
"labels": [
"Country"
],
"properties": {
"name": "阿联酋"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 214892,
"start": 55345,
"end": 120802,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120802,
"labels": [
"Country"
],
"properties": {
"name": "阿联酋"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 209684,
"start": 55345,
"end": 120807,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120945,
"labels": [
"Country"
],
"properties": {
"name": "希腊"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 175225,
"start": 55345,
"end": 120945,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120945,
"labels": [
"Country"
],
"properties": {
"name": "希腊"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 138706,
"start": 55345,
"end": 120965,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120967,
"labels": [
"Country"
],
"properties": {
"name": "意大利"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 101540,
"start": 55345,
"end": 120967,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120967,
"labels": [
"Country"
],
"properties": {
"name": "意大利"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
},
"segments": [
{
"start": {
"identity": 55345,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴蓓蕾纺织品有限公司",
"setup_time": "2015/6/2",
"address": "绍兴市柯桥区柯桥宝汇商务大厦1幢0912室",
"captial": "0万人民币",
"credit_code": "91330621076227391Q"
}
},
"relationship": {
"identity": 37085,
"start": 55345,
"end": 120861,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
}
}
],
"length": 1.0
},
"score": 2.25
},
{
"p": {
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"relationship": {
"identity": 670921,
"start": 61009,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
},
"score": 2.242857142857143
},
{
"p": {
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"end": {
"identity": 120967,
"labels": [
"Country"
],
"properties": {
"name": "意大利"
}
},
"segments": [
{
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"relationship": {
"identity": 571233,
"start": 61009,
"end": 120967,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120967,
"labels": [
"Country"
],
"properties": {
"name": "意大利"
}
}
}
],
"length": 1.0
},
"score": 2.242857142857143
},
{
"p": {
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
},
"segments": [
{
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"relationship": {
"identity": 462927,
"start": 61009,
"end": 120810,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
}
}
],
"length": 1.0
},
"score": 2.242857142857143
},
{
"p": {
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"end": {
"identity": 120945,
"labels": [
"Country"
],
"properties": {
"name": "希腊"
}
},
"segments": [
{
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"relationship": {
"identity": 313987,
"start": 61009,
"end": 120945,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120945,
"labels": [
"Country"
],
"properties": {
"name": "希腊"
}
}
}
],
"length": 1.0
},
"score": 2.242857142857143
},
{
"p": {
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"end": {
"identity": 121013,
"labels": [
"Country"
],
"properties": {
"name": "孟加拉国"
}
},
"segments": [
{
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"relationship": {
"identity": 238328,
"start": 61009,
"end": 121013,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 121013,
"labels": [
"Country"
],
"properties": {
"name": "孟加拉国"
}
}
}
],
"length": 1.0
},
"score": 2.242857142857143
},
{
"p": {
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
},
"segments": [
{
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"relationship": {
"identity": 220651,
"start": 61009,
"end": 120807,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
}
}
],
"length": 1.0
},
"score": 2.242857142857143
},
{
"p": {
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
},
"segments": [
{
"start": {
"identity": 61009,
"labels": [
"Enterprise"
],
"properties": {
"name": "绍兴千海进出口有限公司",
"setup_time": "2017/4/18",
"address": "绍兴袍江启圣路以南与越英路交叉口生产车间",
"captial": "0万人民币",
"credit_code": "91330600050119683C"
}
},
"relationship": {
"identity": 19112,
"start": 61009,
"end": 120861,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
}
}
],
"length": 1.0
},
"score": 2.242857142857143
},
{
"p": {
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"relationship": {
"identity": 704329,
"start": 44255,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
},
"score": 2.073078749505342
},
{
"p": {
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"end": {
"identity": 120913,
"labels": [
"Country"
],
"properties": {
"name": "伊朗"
}
},
"segments": [
{
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"relationship": {
"identity": 502695,
"start": 44255,
"end": 120913,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120913,
"labels": [
"Country"
],
"properties": {
"name": "伊朗"
}
}
}
],
"length": 1.0
},
"score": 2.073078749505342
},
{
"p": {
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
},
"segments": [
{
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"relationship": {
"identity": 484005,
"start": 44255,
"end": 120965,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
}
}
],
"length": 1.0
},
"score": 2.073078749505342
},
{
"p": {
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
},
"segments": [
{
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"relationship": {
"identity": 478870,
"start": 44255,
"end": 120810,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
}
}
],
"length": 1.0
},
"score": 2.073078749505342
},
{
"p": {
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
},
"segments": [
{
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"relationship": {
"identity": 274297,
"start": 44255,
"end": 120786,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120786,
"labels": [
"Country"
],
"properties": {
"name": "印度"
}
}
}
],
"length": 1.0
},
"score": 2.073078749505342
},
{
"p": {
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
},
"segments": [
{
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"relationship": {
"identity": 83384,
"start": 44255,
"end": 120807,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
}
}
],
"length": 1.0
},
"score": 2.073078749505342
},
{
"p": {
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
},
"segments": [
{
"start": {
"identity": 44255,
"labels": [
"Enterprise"
],
"properties": {
"name": "宁波海天精工股份有限公司",
"setup_time": "2011/9/14",
"address": "宁波市北仑区黄山西路235号",
"captial": "0万人民币",
"credit_code": "0"
}
},
"relationship": {
"identity": 37818,
"start": 44255,
"end": 120861,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
}
}
],
"length": 1.0
},
"score": 2.073078749505342
},
{
"p": {
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
},
"segments": [
{
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"relationship": {
"identity": 624028,
"start": 10,
"end": 122725,
"type": "type",
"properties": {
"name": "类型"
}
},
"end": {
"identity": 122725,
"labels": [
"Type"
],
"properties": {
"name": "服务型"
}
}
}
],
"length": 1.0
},
"score": 0.0
},
{
"p": {
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
},
"segments": [
{
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"relationship": {
"identity": 604982,
"start": 10,
"end": 120810,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120810,
"labels": [
"Country"
],
"properties": {
"name": "土耳其"
}
}
}
],
"length": 1.0
},
"score": 0.0
},
{
"p": {
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
},
"segments": [
{
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"relationship": {
"identity": 577929,
"start": 10,
"end": 120965,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120965,
"labels": [
"Country"
],
"properties": {
"name": "俄罗斯"
}
}
}
],
"length": 1.0
},
"score": 0.0
},
{
"p": {
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"end": {
"identity": 120911,
"labels": [
"Country"
],
"properties": {
"name": "乌克兰"
}
},
"segments": [
{
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"relationship": {
"identity": 406404,
"start": 10,
"end": 120911,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120911,
"labels": [
"Country"
],
"properties": {
"name": "乌克兰"
}
}
}
],
"length": 1.0
},
"score": 0.0
},
{
"p": {
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"end": {
"identity": 120945,
"labels": [
"Country"
],
"properties": {
"name": "希腊"
}
},
"segments": [
{
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"relationship": {
"identity": 219530,
"start": 10,
"end": 120945,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120945,
"labels": [
"Country"
],
"properties": {
"name": "希腊"
}
}
}
],
"length": 1.0
},
"score": 0.0
},
{
"p": {
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
},
"segments": [
{
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"relationship": {
"identity": 115562,
"start": 10,
"end": 120807,
"type": "export",
"properties": {
"name": "出口"
}
},
"end": {
"identity": 120807,
"labels": [
"Country"
],
"properties": {
"name": "越南"
}
}
}
],
"length": 1.0
},
"score": 0.0
},
{
"p": {
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
},
"segments": [
{
"start": {
"identity": 10,
"labels": [
"Enterprise"
],
"properties": {
"name": "玉环达丰环保设备有限公司",
"setup_time": "2007/5/31",
"address": "玉环市芦浦镇漩门工业城",
"captial": "2000.0万人民币",
"credit_code": "91331021148341995W"
}
},
"relationship": {
"identity": 31637,
"start": 10,
"end": 120861,
"type": "locate",
"properties": {
"name": "所在地区"
}
},
"end": {
"identity": 120861,
"labels": [
"Region"
],
"properties": {
"name": "浙江省"
}
}
}
],
"length": 1.0
},
"score": 0.0
}
]
\ No newline at end of file
import { createApp } from 'vue'
import App from './App.vue'
// 创建Vue应用实例
const app = createApp(App)
// 同步导入路由和状态管理
import router from './router/index.js'
import store from './store/index.js'
// 使用路由和状态管理
app.use(router)
app.use(store)
// 挂载应用
app.mount('#app')
\ No newline at end of file
<template>
<div class="app-container" :class="{ 'dark-mode': isDarkMode }">
<!-- Header -->
<header class="app-header">
<div class="header-left">
<img src="/favicon.png" alt="" class="logo">
<div>长沙伊测电子科技有限公司</div>
</div>
<div class="header-center">
<nav class="nav-tabs">
<button
class="nav-tab"
:class="{ active: currentTab === 'knowledge-base' }"
@click="switchTab('knowledge-base')">
💬 知识库
</button>
<button
class="nav-tab"
:class="{ active: currentTab === 'knowledge-graph' }"
@click="switchTab('knowledge-graph')">
📊 知识图谱
</button>
</nav>
</div>
<div class="header-right">
<div class="user-info">
<span class="username">{{ username }}</span>
<button class="logout-btn" @click="handleLogout">退出</button>
</div>
<button class="theme-toggle" @click="toggleDarkMode">
{{ isDarkMode ? '☀️' : '🌙' }}
</button>
</div>
</header>
<!-- Main Content -->
<main class="main-content">
<router-view />
</main>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
import { useRouter, useRoute } from 'vue-router';
const router = useRouter();
const route = useRoute();
const currentTab = ref('knowledge-base');
const isDarkMode = ref(false);
const username = ref('管理员');
// 切换暗色模式
function toggleDarkMode() {
isDarkMode.value = !isDarkMode.value;
localStorage.setItem('isDarkMode', isDarkMode.value);
}
// 退出登录
function handleLogout() {
if (confirm('确定要退出登录吗?')) {
localStorage.removeItem('username');
localStorage.removeItem('token');
alert('已退出登录');
}
}
// 导航切换函数
function switchTab(tabName) {
currentTab.value = tabName;
if (tabName === 'knowledge-base') {
router.push('/knowledge-base');
} else if (tabName === 'knowledge-graph') {
router.push('/knowledge-graph');
}
}
// 监听路由变化,更新当前标签
watch(() => route.path, (newPath) => {
if (newPath.startsWith('/knowledge-base')) {
currentTab.value = 'knowledge-base';
} else if (newPath.startsWith('/knowledge-graph')) {
currentTab.value = 'knowledge-graph';
}
}, { immediate: true });
// 初始化
onMounted(() => {
const savedDarkMode = localStorage.getItem('isDarkMode');
if (savedDarkMode !== null) {
isDarkMode.value = savedDarkMode === 'true';
}
const savedUsername = localStorage.getItem('username');
if (savedUsername) {
username.value = savedUsername;
}
const currentPath = route.path;
if (currentPath.startsWith('/knowledge-graph')) {
currentTab.value = 'knowledge-graph';
} else {
currentTab.value = 'knowledge-base';
}
});
</script>
<style scoped>
.app-container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
max-width: 100vw;
max-height: 100vh;
background: #f8f9fa;
transition: all 0.3s ease;
overflow: hidden;
}
.app-container.dark-mode {
background: #1a1b1e;
color: #e2e8f0;
}
/* Header Styles */
.app-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
height: 60px;
background: white;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
transition: all 0.3s ease;
}
.dark-mode .app-header {
background: #2d3748;
border-bottom-color: rgba(255, 255, 255, 0.1);
}
.header-left {
flex: 1;
color: black;
display:flex;
align-items: center;
gap: 10px;
}
.logo {
height: 32px;
width: auto;
transition: opacity 0.3s ease;
}
.logo:hover {
opacity: 0.8;
}
.header-center {
flex: 1;
display: flex;
justify-content: center;
}
.nav-tabs {
display: flex;
gap: 8px;
background: rgba(0, 0, 0, 0.05);
padding: 4px;
border-radius: 8px;
transition: background 0.3s ease;
}
.dark-mode .nav-tabs {
background: rgba(255, 255, 255, 0.05);
}
.nav-tab {
padding: 8px 16px;
border: none;
border-radius: 6px;
background: transparent;
color: #4a5568;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 6px;
}
.dark-mode .nav-tab {
color: #a0aec0;
}
.nav-tab:hover {
background: rgba(0, 0, 0, 0.1);
}
.dark-mode .nav-tab:hover {
background: rgba(255, 255, 255, 0.1);
}
.nav-tab.active {
background: white;
color: #007bff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.dark-mode .nav-tab.active {
background: #4a5568;
color: #63b3ed;
}
.header-right {
flex: 1;
display: flex;
justify-content: flex-end;
align-items: center;
gap: 15px;
}
.user-info {
display: flex;
align-items: center;
gap: 10px;
}
.username {
font-size: 14px;
color: #4a5568;
}
.dark-mode .username {
color: #a0aec0;
}
.logout-btn {
padding: 6px 12px;
border: 1px solid #e2e8f0;
border-radius: 4px;
background: white;
color: #4a5568;
cursor: pointer;
font-size: 12px;
transition: all 0.3s ease;
}
.dark-mode .logout-btn {
background: #4a5568;
border-color: #718096;
color: #e2e8f0;
}
.logout-btn:hover {
background: #f7fafc;
}
.dark-mode .logout-btn:hover {
background: #2d3748;
}
.theme-toggle {
padding: 8px;
border: none;
border-radius: 50%;
background: rgba(0, 0, 0, 0.05);
cursor: pointer;
font-size: 16px;
transition: all 0.3s ease;
}
.dark-mode .theme-toggle {
background: rgba(255, 255, 255, 0.1);
}
.theme-toggle:hover {
transform: scale(1.1);
}
/* Main Content */
.main-content {
flex: 1;
overflow: hidden;
position: relative;
height: calc(100vh - 60px);
width: 100vw;
max-width: 100vw;
}
</style>
\ No newline at end of file
<template>
<div class="chat-container" :class="{ 'dark-mode': isDarkMode }">
<div class="history-sidebar" :class="{ 'collapsed': !showSidebar }">
<div class="history-header">
<button class="new-chat" @click="startNewChat">
<i class="icon">+</i> 新对话
</button>
<button class="toggle-btn" @click="toggleSidebar">
{{ showSidebar ? '<<' : '>>' }}
</button>
</div>
<div class="history-list">
<div
v-for="session in sessions"
:key="session.id"
class="history-item"
:class="{ 'active': currentSessionId === session.sessionId }"
@click="loadSession(session.sessionId)"
>
<span class="history-title">{{ getSessionTitle(session) }}</span>
<button class="delete-btn" @click.stop="deleteSession(session.sessionId)">×</button>
</div>
</div>
</div>
<div class="chat-main">
<button class="expand-btn" @click="toggleSidebar" v-show="!showSidebar">
>>
</button>
<div class="messages-container">
<ChatMessage
v-for="(msg, index) in messages"
:key="index"
:content="msg.content"
:role="msg.role"
:isThinking="msg.isThinking"
:reasoning="msg.reasoning"
/>
</div>
<ChatInput @send="sendMessage" :isLoading="isLoading" />
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import ChatMessage from '../components/ChatMessage.vue';
import ChatInput from '../components/ChatInput.vue';
// import { API_CONFIG } from '../config';
import { chatDB } from '../services/db';
import { v4 as uuidv4 } from 'uuid';
const messages = ref([]);
const isLoading = ref(false);
const sessions = ref([]);
const currentSessionId = ref('');
const showSidebar = ref(true);
const isDarkMode = ref(false);
// 初始化
onMounted(async () => {
// 读取保存的暗色模式设置
const savedDarkMode = localStorage.getItem('isDarkMode');
if (savedDarkMode !== null) {
isDarkMode.value = savedDarkMode === 'true';
}
await loadSessions();
if (sessions.value.length === 0) {
startNewChat();
} else {
// 加载最近的会话
loadSession(sessions.value[0].sessionId);
}
});
// 加载所有会话
async function loadSessions() {
try {
sessions.value = await chatDB.getAllSessions();
} catch (error) {
console.error('加载会话列表失败:', error);
}
}
// 加载指定会话
async function loadSession(sessionId) {
try {
const sessionMessages = await chatDB.getSessionMessages(sessionId);
messages.value = sessionMessages;
currentSessionId.value = sessionId;
} catch (error) {
console.error('加载会话消息失败:', error);
}
}
// 开始新对话
async function startNewChat() {
currentSessionId.value = uuidv4();
messages.value = [{
role: 'assistant',
content: '您好!有什么我可以帮你的吗?'
}];
// 保存欢迎消息
try {
await chatDB.saveMessage(currentSessionId.value, messages.value[0]);
await loadSessions(); // 刷新会话列表
} catch (error) {
console.error('保存欢迎消息失败:', error);
}
}
// 删除会话
async function deleteSession(sessionId) {
if (!confirm('确定要删除这个会话吗?')) return;
try {
await chatDB.deleteSession(sessionId);
await loadSessions();
if (currentSessionId.value === sessionId) {
if (sessions.value.length > 0) {
loadSession(sessions.value[0].sessionId);
} else {
startNewChat();
}
}
} catch (error) {
console.error('删除会话失败:', error);
}
}
// 发送消息
async function sendMessage(content) {
if (isLoading.value) return;
isLoading.value = true;
// 保存用户消息
const userMessage = {
role: 'user',
content: content
};
messages.value.push(userMessage);
await chatDB.saveMessage(currentSessionId.value, userMessage);
// 添加思考状态的消息
const assistantMessage = {
role: 'assistant',
content: '',
isThinking: true,
reasoning: ''
};
messages.value.push(assistantMessage);
try {
// 调用 API
const response = await fetch('/api/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
// 'Authorization': `Bearer ${API_CONFIG.apiKey}`,
'Accept': 'application/json'
},
body: JSON.stringify({
// model: API_CONFIG.modelName,
messages: messages.value
.filter(msg => !msg.isThinking) // 过滤掉思考中的消息
.filter(msg => !(msg.role === 'assistant' && msg.content.includes('DeepSeek') && msg.content.includes('你好'))) // 过滤掉初始化欢迎消息
.map(msg => ({
role: msg.role,
content: msg.content
})),
stream: true
})
});
if (!response.ok) {
throw new Error('API 请求失败');
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') continue;
try {
const parsed = JSON.parse(data);
const delta = parsed.choices[0].delta;
// 处理推理内容
if (delta.reasoning_content) {
assistantMessage.reasoning = (assistantMessage.reasoning || '') + delta.reasoning_content;
// 强制更新视图
messages.value = [...messages.value];
continue;
}
// 处理回答内容
if (delta.content) {
if (assistantMessage.isThinking) {
assistantMessage.isThinking = false;
assistantMessage.content = '';
}
assistantMessage.content += delta.content;
// 强制更新视图
messages.value = [...messages.value];
}
} catch (e) {
console.error('解析响应数据时出错:', e);
}
}
}
}
// 保存完整的助手消息
await chatDB.saveMessage(currentSessionId.value, {
role: 'assistant',
content: assistantMessage.content,
reasoning: assistantMessage.reasoning
});
await loadSessions(); // 刷新会话列表
} catch (error) {
console.error('发送消息失败:', error);
messages.value.pop(); // 移除思考中的消息
messages.value.push({
role: 'assistant',
content: '抱歉,发生了错误,请稍后重试。'
});
} finally {
isLoading.value = false;
}
}
// 获取会话标题
function getSessionTitle(session) {
// 如果是系统欢迎消息,则显示"新对话"
if (session.role === 'assistant' && session.content.includes('DeepSeek')) {
return '新对话';
}
// 使用用户的消息作为标题
const title = session.content;
return title.slice(0, 20) + (title.length > 20 ? '...' : '');
}
// 切换侧边栏
function toggleSidebar() {
showSidebar.value = !showSidebar.value;
}
</script>
<style scoped>
.chat-container {
display: flex;
height: calc(100vh - 60px); /* 减去顶部导航栏高度 */
width: 100vw;
background: #f8f9fa;
position: relative;
transition: all 0.3s ease;
overflow: hidden;
}
.chat-container.dark-mode {
background: #1a1b1e;
color: #e2e8f0;
}
.theme-toggle {
position: fixed;
right: 20px;
top: 20px;
width: 40px;
height: 40px;
border-radius: 50%;
border: 1px solid rgba(0, 0, 0, 0.1);
background: white;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
transition: all 0.3s ease;
z-index: 100;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.dark-mode .theme-toggle {
background: #2d3748;
border-color: rgba(255, 255, 255, 0.1);
color: #e2e8f0;
}
.dark-mode .history-sidebar {
background: #2d3748;
border-right-color: rgba(255, 255, 255, 0.1);
}
.dark-mode .history-header {
background: rgba(0, 0, 0, 0.2);
border-bottom-color: rgba(255, 255, 255, 0.1);
}
.dark-mode .new-chat {
background: #4a5568;
}
.dark-mode .new-chat:hover {
background: #2d3748;
}
.dark-mode .toggle-btn {
background: rgba(45, 55, 72, 0.9);
border-color: rgba(255, 255, 255, 0.1);
color: #e2e8f0;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}
.dark-mode .toggle-btn:hover {
background: rgba(45, 55, 72, 1);
transform: scale(1.05);
}
.dark-mode .history-item {
background: rgba(255, 255, 255, 0.05);
color: #e2e8f0;
}
.dark-mode .history-item:hover {
background: rgba(255, 255, 255, 0.1);
}
.dark-mode .history-item.active {
background: rgba(66, 153, 225, 0.15);
border-color: rgba(66, 153, 225, 0.3);
}
.dark-mode .history-title {
color: #e2e8f0;
}
.dark-mode .delete-btn {
color: #718096;
}
.dark-mode .delete-btn:hover {
color: #fc8181;
}
.dark-mode .chat-main {
background: #1a1b1e;
}
.dark-mode .expand-btn {
background: rgba(45, 55, 72, 0.95);
border-color: rgba(255, 255, 255, 0.1);
color: #e2e8f0;
box-shadow: 4px 0 8px rgba(0, 0, 0, 0.2);
}
.dark-mode .expand-btn:hover {
background: rgb(45, 55, 72);
width: 36px;
box-shadow: 4px 0 12px rgba(0, 0, 0, 0.3);
}
.expand-btn {
position: fixed;
left: 0;
top: 50%;
transform: translateY(-50%);
padding: 12px;
width: 32px;
height: 40px;
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(0, 0, 0, 0.08);
border-left: none;
border-radius: 0 8px 8px 0;
cursor: pointer;
color: #4a5568;
box-shadow: 4px 0 8px rgba(0, 0, 0, 0.05);
opacity: 0;
transition: all 0.3s ease;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.expand-btn:hover {
background: #fff;
color: #2d3748;
width: 36px;
box-shadow: 4px 0 12px rgba(0, 0, 0, 0.08);
}
.history-sidebar.collapsed + .chat-main .expand-btn {
opacity: 1;
}
.history-sidebar {
width: 260px;
height: 100%;
border-right: 1px solid rgba(0, 0, 0, 0.06);
background: #f1f3f5;
display: flex;
flex-direction: column;
transition: all 0.3s ease;
}
.history-sidebar.collapsed {
width: 0;
overflow: hidden;
}
.history-header {
padding: 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.06);
display: flex;
align-items: center;
gap: 8px;
background: rgba(255, 255, 255, 0.7);
}
.new-chat {
flex: 1;
padding: 8px 16px;
border: none;
border-radius: 6px;
background: #4a5568;
color: white;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
font-size: 14px;
transition: all 0.2s;
}
.new-chat:hover {
background: #2d3748;
}
.toggle-btn {
padding: 8px;
width: 32px;
height: 32px;
border: 1px solid rgba(0, 0, 0, 0.08);
border-radius: 8px;
background: rgba(255, 255, 255, 0.9);
cursor: pointer;
color: #4a5568;
font-size: 14px;
transition: all 0.3s ease;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
}
.toggle-btn:hover {
background: rgba(255, 255, 255, 1);
color: #2d3748;
transform: scale(1.05);
}
.history-list {
flex: 1;
overflow-y: auto;
padding: 16px;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
}
.history-list::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
.history-item {
padding: 12px 16px;
margin-bottom: 8px;
border-radius: 6px;
background: rgba(255, 255, 255, 0.7);
cursor: pointer;
display: flex;
align-items: center;
gap: 8px;
transition: all 0.2s;
border: 1px solid transparent;
}
.history-item:hover {
background: rgba(255, 255, 255, 0.9);
}
.history-item.active {
background: #e3f2fd;
border-color: #bbdefb;
}
.history-title {
flex: 1;
font-size: 14px;
color: #2d3748;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.delete-btn {
padding: 4px 8px;
border: none;
background: transparent;
color: #999;
cursor: pointer;
font-size: 16px;
opacity: 0;
transition: all 0.2s;
}
.history-item:hover .delete-btn {
opacity: 1;
}
.delete-btn:hover {
color: #ff4d4f;
}
.chat-main {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
background: white;
position: relative;
}
.messages-container {
flex: 1;
overflow-y: auto;
padding: 20px;
padding-bottom: 100px; /* 为输入框留出空间 */
scroll-behavior: smooth;
margin-bottom: 20px;
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
}
.messages-container::-webkit-scrollbar {
display: none; /* Chrome/Safari */
}
.icon {
font-style: normal;
font-weight: bold;
}
/* 隐藏滚动条 */
.history-list::-webkit-scrollbar,
.messages-container::-webkit-scrollbar {
width: 0px;
height: 0px;
display: none;
}
.history-list::-webkit-scrollbar-thumb,
.messages-container::-webkit-scrollbar-thumb {
background: transparent;
border-radius: 0px;
}
.history-list::-webkit-scrollbar-track,
.messages-container::-webkit-scrollbar-track {
background: transparent;
}
</style>
\ No newline at end of file
<template>
<div class="gContainer">
<!-- <d3graph /> -->
<gSearch @getData="update" />
<d3graph
:data="data"
:names="names"
:labels="labels"
:linkTypes="linkTypes"
/>
</div>
</template>
<script>
import gSearch from '../../components/gSearch.vue'
import d3graph from '../../components/d3graph.vue'
export default {
components: {
gSearch,
d3graph
},
data () {
return {
// d3jsonParser()处理 json 后返回的结果
data: {
nodes: [],
links: []
},
names: ['企业', '贸易类型', '地区', '国家'],
labels: ['Enterprise', 'Type', 'Region', 'Country'],
linkTypes: ['', 'type', 'locate', 'export']
}
},
methods: {
// 视图更新
update (json) {
console.log('update')
console.log(json)
this.d3jsonParser(json)
},
/*eslint-disable*/
// 解析json数据,主要负责数据的去重、标准化
d3jsonParser (json) {
const nodes =[]
const links = [] // 存放节点和关系
const nodeSet = [] // 存放去重后nodes的id
// 使用vue直接通过require获取本地json,不再需要使用d3.json获取数据
// d3.json('./../data/records.json', function (error, data) {
// if (error) throw error
// graph = data
// console.log(graph[0].p)
// })
for (let item of json) {
for (let segment of item.p.segments) {
// 重新更改data格式
if (nodeSet.indexOf(segment.start.identity) == -1) {
nodeSet.push(segment.start.identity)
nodes.push({
id: segment.start.identity,
label: segment.start.labels[0],
properties: segment.start.properties
})
}
if (nodeSet.indexOf(segment.end.identity) == -1) {
nodeSet.push(segment.end.identity)
nodes.push({
id: segment.end.identity,
label: segment.end.labels[0],
properties: segment.end.properties
})
}
links.push({
source: segment.relationship.start,
target: segment.relationship.end,
type: segment.relationship.type,
properties: segment.relationship.properties
})
}
}
console.log(nodes)
console.log(links)
// this.links = links
// this.nodes = nodes
this.data = { nodes, links }
// return { nodes, links }
}
}
}
</script>
<style lang="scss" scoped>
.gContainer {
position: relative;
background-color: #9dadc1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
overflow: hidden;
width: 100vw;
height: calc(100vh - 60px); /* 减去顶部导航栏高度 */
}
</style>
<template>
<div class="gContainer">
<gSearch @getData="update" />
<!-- <threeGraph /> -->
<threeGraph
:data="data"
:names="names"
:labels="labels"
:linkTypes="linkTypes"
/>
</div>
</template>
<script>
// @ is an alias to /src
import gSearch from '../../components/gSearch.vue'
import threeGraph from '../../components/threeGraph.vue'
export default {
name: 'threeView',
components: {
gSearch,
threeGraph
},
data () {
return {
// d3jsonParser()处理 json 后返回的结果
data: {
nodes: [],
links: []
},
names: ['企业', '贸易类型', '地区', '国家'],
labels: ['Enterprise', 'Type', 'Region', 'Country'],
linkTypes: ['', 'type', 'locate', 'export']
}
},
methods: {
// 视图更新
update (json) {
console.log('update')
console.log(json)
this.d3jsonParser(json)
},
/*eslint-disable*/
// 解析json数据,主要负责数据的去重、标准化
d3jsonParser (json) {
const nodes =[]
const links = [] // 存放节点和关系
const nodeSet = [] // 存放去重后nodes的id
// 使用vue直接通过require获取本地json,不再需要使用d3.json获取数据
// d3.json('./../data/records.json', function (error, data) {
// if (error) throw error
// graph = data
// console.log(graph[0].p)
// })
for (let item of json) {
for (let segment of item.p.segments) {
// 重新更改data格式
if (nodeSet.indexOf(segment.start.identity) == -1) {
nodeSet.push(segment.start.identity)
nodes.push({
id: segment.start.identity,
label: segment.start.labels[0],
properties: segment.start.properties
})
}
if (nodeSet.indexOf(segment.end.identity) == -1) {
nodeSet.push(segment.end.identity)
nodes.push({
id: segment.end.identity,
label: segment.end.labels[0],
properties: segment.end.properties
})
}
links.push({
source: segment.relationship.start,
target: segment.relationship.end,
type: segment.relationship.type,
properties: segment.relationship.properties
})
}
}
console.log(nodes)
console.log(links)
// this.links = links
// this.nodes = nodes
this.data = { nodes, links }
// return { nodes, links }
}
}
}
</script>
<style lang="scss" scoped>
.gContainer {
position: relative;
background-color: #9dadc1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
overflow: hidden;
width: 100vw;
height: calc(100vh - 60px); /* 减去顶部导航栏高度 */
}
</style>
<template>
<div class="graph-container">
<!-- 子导航栏 - 移动到顶部作为标签页 -->
<div class="sub-nav">
<router-link
to="/knowledge-graph/2d"
class="sub-nav-link"
:class="{ active: $route.path === '/knowledge-graph/2d' }">
📈 2D知识图谱
</router-link>
<router-link
to="/knowledge-graph/3d"
class="sub-nav-link"
:class="{ active: $route.path === '/knowledge-graph/3d' }">
🌐 3D知识图谱
</router-link>
</div>
<router-view/>
</div>
</template>
<script setup>
// 不需要额外的重定向逻辑,因为路由配置已经处理了默认重定向
</script>
<style scoped>
.graph-container {
min-height: calc(100vh - 60px); /* 减去顶部导航栏高度 */
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
transition: background 0.3s ease;
position: relative;
overflow: hidden;
}
.sub-nav {
display: flex;
gap: 20px;
padding: 15px 20px;
background: rgba(255, 255, 255, 0.8);
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
backdrop-filter: blur(10px);
}
.sub-nav-link {
padding: 8px 16px;
text-decoration: none;
color: #666;
border-radius: 6px;
transition: all 0.3s ease;
font-weight: 500;
}
.sub-nav-link:hover {
background: rgba(0, 0, 0, 0.05);
color: #333;
}
.sub-nav-link.active {
background: #007bff;
color: white;
box-shadow: 0 2px 4px rgba(0, 123, 255, 0.3);
}
/* 暗色模式支持 */
.app-container.dark-mode .sub-nav {
background: rgba(45, 55, 72, 0.8);
border-bottom-color: rgba(255, 255, 255, 0.1);
}
.app-container.dark-mode .sub-nav-link {
color: #a0aec0;
}
.app-container.dark-mode .sub-nav-link:hover {
background: rgba(255, 255, 255, 0.1);
color: #e2e8f0;
}
.app-container.dark-mode .sub-nav-link.active {
background: #4299e1;
color: white;
}
/* 隐藏滚动条 */
.graph-container::-webkit-scrollbar {
width: 0px;
height: 0px;
display: none;
}
</style>
\ No newline at end of file
let _d3 = null
// 为d3注册该右键菜单插件
function install (d3) {
_d3 = d3
// 使用更安全的方式添加contextMenu方法
if (d3 && !d3.contextMenu) {
try {
Object.defineProperty(d3, 'contextMenu', {
value: contextMenu,
writable: true,
configurable: true
})
} catch (error) {
// 如果defineProperty失败,直接赋值作为后备方案
d3.contextMenu = contextMenu
}
}
}
const contextMenu = function (menu, openCallback) {
// create the div element that will hold the context menu
_d3.selectAll('.d3-context-menu').data([1])
.enter()
.append('div')
.attr('class', 'd3-context-menu')
// close menu
_d3.select('body').on('click.d3-context-menu', function () {
_d3.select('.d3-context-menu').style('display', 'none')
})
// this gets executed when a contextmenu event occurs
return function (event, data) {
console.log(event)
// 指向右键触发的节点
var elm = this
_d3.selectAll('.d3-context-menu').html('')
var list = _d3.selectAll('.d3-context-menu').append('ul')
list.selectAll('li').data(menu).enter()
.append('li')
.html(function (d) {
return d.title
})
.on('click', function (e, d) {
// console.log(d)
d.action(elm, data)
_d3.select('.d3-context-menu').style('display', 'none')
})
// the openCallback allows an action to fire before the menu is displayed
// an example usage would be closing a tooltip
if (openCallback) openCallback(data)
// display context menu
_d3.select('.d3-context-menu')
.style('left', (event.pageX - 2) + 'px')
.style('top', (event.pageY - 2) + 'px')
.style('display', 'block')
event.preventDefault()
}
}
export default install
.d3-context-menu {
position: absolute;
display: none;
background-color: #f2f2f2;
border-radius: 4px;
font-family: Arial, sans-serif;
font-size: 14px;
min-width: 150px;
border: 1px solid #d4d4d4;
z-index:1200;
}
.d3-context-menu ul {
list-style-type: none;
margin: 4px 0px;
padding: 0px;
cursor: default;
}
.d3-context-menu ul li {
padding: 4px 16px;
}
.d3-context-menu ul li:hover {
background-color: #4677f8;
color: #fefefe;
}
\ No newline at end of file
import { createRouter, createWebHistory } from 'vue-router'
// 创建布局组件
const Layout = () => import('../pages/Layout.vue')
// 优化后的路由结构
const routes = [
{
path: '/',
component: Layout, // 使用专门的布局组件
redirect: '/knowledge-base',
children: [
{
path: '/knowledge-base',
name: 'KnowledgeBase',
component: () => import('../pages/chats.vue'),
meta: { title: '知识库', icon: '💬' }
},
{
path: '/knowledge-graph',
name: 'KnowledgeGraph',
component: () => import('../pages/graph.vue'),
meta: { title: '知识图谱', icon: '📊' },
redirect: '/knowledge-graph/2d',
children: [
{
path: '2d',
name: 'KnowledgeGraph2D',
component: () => import('../pages/components/2dView.vue'),
meta: { title: '2D知识图谱' }
},
{
path: '3d',
name: 'KnowledgeGraph3D',
component: () => import('../pages/components/3dView.vue'),
meta: { title: '3D知识图谱' }
}
]
}
]
},
// 兼容旧路由的重定向
{
path: '/chats',
redirect: '/knowledge-base'
},
{
path: '/graph',
redirect: '/knowledge-graph'
},
{
path: '/2dView',
redirect: '/knowledge-graph/2d'
},
{
path: '/3dView',
redirect: '/knowledge-graph/3d'
},
// 404页面
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
component: () => import('../pages/chats.vue') // 暂时使用知识库页面作为404页面
}
]
const router = createRouter({
history: createWebHistory(),
routes
})
// 路由守卫
router.beforeEach((to, from, next) => {
// 设置页面标题
if (to.meta && to.meta.title) {
document.title = `${to.meta.title} - 长沙伊测电子科技`
}
// 检查权限(可以在这里添加登录验证逻辑)
const isAuthenticated = localStorage.getItem('token') || true // 暂时允许所有访问
if (!isAuthenticated && to.path !== '/login') {
next('/login')
} else {
next()
}
})
export default router
const DB_NAME = 'deepseekChat';
const DB_VERSION = 1;
const STORE_NAME = 'messages';
class ChatDatabase {
constructor() {
this.db = null;
}
async init() {
if (this.db) return;
return new Promise((resolve, reject) => {
const request = indexedDB.open(DB_NAME, DB_VERSION);
request.onerror = () => {
reject(request.error);
};
request.onsuccess = () => {
this.db = request.result;
resolve();
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains(STORE_NAME)) {
// 创建消息存储,使用自增 ID 作为键
const store = db.createObjectStore(STORE_NAME, {
keyPath: 'id',
autoIncrement: true
});
// 创建会话 ID 索引,用于按会话分组查询消息
store.createIndex('sessionId', 'sessionId', { unique: false });
// 创建时间戳索引,用于按时间排序
store.createIndex('timestamp', 'timestamp', { unique: false });
}
};
});
}
async saveMessage(sessionId, message) {
await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const messageData = {
...message,
sessionId,
timestamp: Date.now()
};
const request = store.add(messageData);
request.onsuccess = () => resolve(request.result);
request.onerror = () => reject(request.error);
});
}
async getSessionMessages(sessionId) {
await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const index = store.index('sessionId');
const request = index.getAll(IDBKeyRange.only(sessionId));
request.onsuccess = () => {
// 按时间戳排序
const messages = request.result.sort((a, b) => a.timestamp - b.timestamp);
resolve(messages);
};
request.onerror = () => reject(request.error);
});
}
async getAllSessions() {
await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([STORE_NAME], 'readonly');
const store = transaction.objectStore(STORE_NAME);
const request = store.getAll();
request.onsuccess = () => {
// 按会话ID分组,找到每个会话的第一条用户消息和最新时间戳
const sessions = request.result.reduce((acc, message) => {
if (!acc[message.sessionId]) {
acc[message.sessionId] = {
sessionId: message.sessionId,
timestamp: message.timestamp,
content: '',
role: ''
};
}
// 更新最新时间戳
if (message.timestamp > acc[message.sessionId].timestamp) {
acc[message.sessionId].timestamp = message.timestamp;
}
// 如果是用户消息,且还没有设置内容或时间更早,则更新为此消息
if (message.role === 'user' &&
(!acc[message.sessionId].content ||
message.timestamp < acc[message.sessionId].timestamp)) {
acc[message.sessionId].content = message.content;
acc[message.sessionId].role = message.role;
}
return acc;
}, {});
// 如果没有用户消息,使用第一条助手消息
Object.values(sessions).forEach(session => {
if (!session.content) {
const firstMessage = request.result.find(m => m.sessionId === session.sessionId);
if (firstMessage) {
session.content = firstMessage.content;
session.role = firstMessage.role;
}
}
});
resolve(Object.values(sessions).sort((a, b) => b.timestamp - a.timestamp));
};
request.onerror = () => reject(request.error);
});
}
async deleteSession(sessionId) {
await this.init();
return new Promise((resolve, reject) => {
const transaction = this.db.transaction([STORE_NAME], 'readwrite');
const store = transaction.objectStore(STORE_NAME);
const index = store.index('sessionId');
const request = index.openCursor(IDBKeyRange.only(sessionId));
request.onsuccess = (event) => {
const cursor = event.target.result;
if (cursor) {
cursor.delete();
cursor.continue();
} else {
resolve();
}
};
request.onerror = () => reject(request.error);
});
}
}
export const chatDB = new ChatDatabase();
\ No newline at end of file
import { createStore } from 'vuex'
export default createStore({
state: {
// 应用状态
isDarkMode: false,
userInfo: null,
currentTab: 'chats'
},
mutations: {
// 同步状态修改
SET_DARK_MODE(state, isDarkMode) {
state.isDarkMode = isDarkMode
},
SET_USER_INFO(state, userInfo) {
state.userInfo = userInfo
},
SET_CURRENT_TAB(state, tab) {
state.currentTab = tab
}
},
actions: {
// 异步操作
toggleDarkMode({ commit, state }) {
const newMode = !state.isDarkMode
commit('SET_DARK_MODE', newMode)
localStorage.setItem('isDarkMode', newMode)
},
loadUserInfo({ commit }) {
const savedUser = localStorage.getItem('username')
if (savedUser) {
commit('SET_USER_INFO', { username: savedUser })
}
}
},
getters: {
// 状态计算
isLoggedIn: state => !!state.userInfo,
username: state => state.userInfo?.username || '管理员'
}
})
:root {
--primary-color: #10a37f;
--background-color: #343541;
--chat-background: #444654;
--text-color: #fff;
--user-message-bg: #343541;
--assistant-message-bg: #444654;
--border-color: #565869;
--hover-color: #4a4b59;
}
* {
box-sizing: border-box;
}
html, body, #app {
height: 100%;
margin: 0;
padding: 0;
font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
overflow: hidden;
width: 100vw;
max-width: 100vw;
}
body {
background-color: var(--background-color);
color: var(--text-color);
line-height: 1.6;
}
.container {
min-height: 100vh;
max-width: 800px;
margin: 0 auto;
padding: 20px;
display: flex;
flex-direction: column;
}
.messages-container {
flex: 1;
margin-bottom: 120px;
padding-bottom: 20px;
overflow-y: auto;
display: flex;
flex-direction: column;
align-items: stretch;
}
.message {
padding: 24px;
margin: 8px 0;
border-radius: 8px;
transition: all 0.3s ease;
animation: message-fade-in 0.5s ease;
max-width: 90%;
}
.user-message {
background-color: var(--user-message-bg);
margin-left: auto;
margin-right: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.assistant-message {
background-color: var(--assistant-message-bg);
margin-right: auto;
margin-left: 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.input-container {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20px;
background: linear-gradient(to bottom, transparent, var(--background-color) 20%);
backdrop-filter: blur(10px);
}
.chat-input {
width: 100%;
max-width: 760px;
margin: 0 auto;
display: block;
padding: 12px 16px;
border-radius: 8px;
border: 1px solid var(--border-color);
background-color: #40414f;
color: var(--text-color);
resize: none;
font-size: 1rem;
line-height: 1.5;
transition: all 0.3s ease;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
.chat-input:focus {
outline: none;
border-color: var(--primary-color);
box-shadow: 0 0 0 2px rgba(16, 163, 127, 0.2);
}
/* 添加动画 */
@keyframes message-fade-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 隐藏滚动条 - 所有浏览器兼容 */
::-webkit-scrollbar {
width: 0px !important;
height: 0px !important;
display: none !important;
}
::-webkit-scrollbar-track {
background: transparent !important;
}
::-webkit-scrollbar-thumb {
background: transparent !important;
border-radius: 0px !important;
}
::-webkit-scrollbar-thumb:hover {
background: transparent !important;
}
/* Firefox */
* {
scrollbar-width: none !important;
scrollbar-color: transparent transparent !important;
}
/* IE/Edge */
* {
-ms-overflow-style: none !important;
}
/* 文本选择样式 */
::selection {
background: rgba(16, 163, 127, 0.2);
color: var(--text-color);
}
\ No newline at end of file
<template>
<div>
<div id="3d-graph" class="three-graph"></div>
<!-- 绘制图例 -->
<div id="indicator">
<!-- 利用item 遍历一个数组 利用index 遍历另外一个数组 -->
<div v-for="(name, index) in names" :key="index">
<span
:data-state="states[index]"
:data-index="index"
:style="{ backgroundColor: states[index] === 'on' ? nodeColors[index] : '#aaa' }"
></span>
{{ name }}
</div>
</div>
<!-- 绘制右边显示结果 -->
<div id="info" v-show="selectNodeData.name !== undefined">
<!-- <h4 :style="{ color: selectNodeData.color }">{{ selectNodeData.name }}</h4>
<p v-for="(item, key) in selectNodeData.properties" :key="item">
<span>{{ key }}</span>
{{ item }}
</p> -->
<el-card
:style="{ backgroundColor: selectNodeData.color }"
class="node-card"
>
<div slot="header" class="clearfix">
<span>{{ selectNodeData.name }}</span>
<el-button
@click="btnEdit"
style="float: right; padding: 3px 0;color: #409EFB;font-size: 15px;"
type="text"
>编辑</el-button>
</div>
<div
v-for="(item, key) in selectNodeData.properties" :key="item"
>
<span style="margin-right: 8px;">{{ (nodeObjMap[key] ? nodeObjMap[key] : key) + ':' }}</span>
<span style="text-align: right;"><b>{{ item }}</b></span>
</div>
</el-card>
</div>
<!-- 编辑框 -->
<el-dialog :visible.sync="dialogFormVisible">
<el-form
:model="temp"
label-position="right"
label-width="86px"
style="width: 500px; margin-left:50px;"
>
<el-form-item
v-for="(value, key) in temp"
:key="key"
:label="nodeObjMap[key] ? nodeObjMap[key] : key"
>
<el-input
v-model="temp[key]"
:readonly="!isEdit"
/>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="cancelEdit">
取消
</el-button>
<el-button type="primary" @click="doEdit">
确定
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import ForceGraph3D from '3d-force-graph'
// threejs的精灵标签,用于文字的展示
import SpriteText from 'three-spritetext'
export default {
name: 'threeGraph',
props: {
data: {
type: Object,
default: function () {
return {
nodes: [],
links: []
}
}
},
/* eslint-disable */
// 自定义图例(数组保证一一对应)
// names 图例名称变量制作图标
// labels 节点的标签名称(与records.json中保证相同)
names: {
type: Array
},
labels: Array,
linkTypes: Array
},
mounted () {
this.threeInit()
},
data () {
return {
// ForceGraph3D对象,供全局调用,实现动态更新
Graph: {},
// threeRender()最终展示到页面上的数据(节点隐藏功能)
nodes: [],
links: [],
// 图例的名称、对应的颜色以及图例状态
states: [],
nodeColors: ['#55cccc', '#aaaaff', '#4e88af', '#ca635f','#FFC0CB', '#BA55D3', '#1E90FF', '#7FFFD4','#FFFF00'],
selectNodeData: {}, // 选中节点的详细信息展示
temp: {}, // 临时存储编辑时的节点信息
dialogFormVisible: false,
isEdit: true,
// 节点属性对应的标签名称
nodeObjMap: {
'address': '注册地址',
'captial': '注册资本',
'credit_code': '信用代码',
'name': '节点名称',
'setup_time': '注册日期'
}
}
},
watch: {
// 当请求到新的数据时,重新渲染
data (newData, oldData) {
console.log(newData, oldData)
this.threeInit()
}
},
methods: {
// 视图更新
update () {
if (this.graph.length <= 20) {
this.graph = require('../data/top5.json')
} else {
this.graph = require('../data/records.json')
}
// console.log(this.graph)
console.log(this.graph.length)
this.neoJsonParser(this.graph)
// console.log(this.Graph)
// 更新前清空DOM内canvas元素
// 注意固定容器的宽高,防止渲染时容器塌陷
document.getElementById('3d-graph').innerHTML = ''
this.threeRender()
// 更新数据暂不能用,卡死
// this.threeUpdate({
// nodes: [],
// links: []
// })
},
// 编辑当前选中节点
btnEdit () {
this.temp = Object.assign({}, this.selectNodeData.properties) // copy obj
this.dialogFormVisible = true
console.log(this.selectNodeData)
},
doEdit () {
// console.log(this.data)
let i = 0
// 更新props的data 和 selectNodeData
this.selectNodeData.name = this.temp.name
this.selectNodeData.properties = this.temp
for (let node of this.data.nodes) {
// console.log(node.id === this.selectNodeData.id)
// console.log(node.id)
// console.log(this.selectNodeData.id)
if (node.id == this.selectNodeData.id) {
// this.$set(this.data.nodes, i, this.selectNodeData)
// this.$set(this.nodes, i, this.selectNodeData)
this.data.nodes[i].properties = this.temp
this.nodes[i].properties = this.temp
break
}
i++
}
this.dialogFormVisible = false
this.threeInit()
this.$message({
message: '更新成功',
type: 'success'
})
},
cancelEdit () {
this.dialogFormVisible = false
},
// d3初始化,包括数据解析、数据渲染
threeInit () {
this.links = this.data.links
this.nodes = this.data.nodes
this.threeRender()
// 数据状态初始化
this.stateInit()
},
// 数据状态初始化
stateInit () {
this.states = Array(this.names.length).fill('on')
},
threeRender () {
// DOM初始化及数据挂载
const elm = document.getElementById('3d-graph')
this.Graph = ForceGraph3D()(elm)
.graphData(this.data)
// 设置画布样式、节点及关系样式、事件绑定等
this.Graph.height(750).width(1200)
.backgroundColor('#9dadc1')
// 节点样式和标签设置
.nodeRelSize(7)
.nodeColor(node => {
let index = 0
switch(node.label) {
case this.labels[0]: break;
case this.labels[1]: index = 1;break;
case this.labels[2]: index = 2;break;
default: index = 3;break;
}
return this.nodeColors[index]
})
// .nodeAutoColorBy('label')
// 给节点添加文字
// .nodeThreeObjectExtend(true)
.nodeThreeObject(node => {
const sprite = new SpriteText(node.properties.name)
sprite.material.depthWrite = false // make sprite background transparent
// 设置文字颜色
let i = 0
// switch(node.label) {
// case this.labels[0]: break;
// case this.labels[1]: index = 1;break;
// case this.labels[2]: index = 2;break;
// default: index = 3;break;
// }
for (;i < this.labels.length;i++) {
if (node.label === this.labels[i]) break
}
sprite.color = this.nodeColors[i]
sprite.textHeight = 8
return sprite
})
.nodeThreeObjectExtend(true)
.nodeLabel(node => `${node.label}: ${node.properties.name}`)
.nodeOpacity(0.75)
// 节点事件绑定
.onNodeHover(node => elm.style.cursor = node ? 'pointer' : null)
.onNodeClick(node => {
console.log(node)
//设置#info h4样式的颜色为该节点的颜色,文本为该节点name
this.$set(this.selectNodeData, 'id', node.id)
this.$set(this.selectNodeData, 'name', node.properties.name)
// 获取节点类型对应的颜色
// let index = 0
// switch(node.label) {
// case 'Enterprise': break;
// case 'Type': index = 1;break;
// case 'Region': index = 2;break;
// default: index = 3;break;
// }
let i = 0
for (;i < this.labels.length;i++) {
if (node.label === this.labels[i]) break
}
this.$set(this.selectNodeData, 'color', this.nodeColors[i])
this.$set(this.selectNodeData, 'properties', node.properties)
})
// 关系样式
// .linkColor('#bbb')
// .linkColor(link => {
// let index = 0
// const colors = ['#faa']
// switch(link.type) {
// case 'export': break;
// case 'type': index = 1;break;
// case 'locate': index = 2;break;
// default: index = 3;break;
// }
// return this.nodeColors[index]
// })
// .linkOpacity(1)
// Spread nodes a little wider
this.Graph.d3Force('charge').strength(-150)
},
threeUpdate (data) {
this.Graph.graphData({
data
})
},
// 随机生成一个规模为N的图
createRandomGraph (N = 300) {
return {
nodes: [...Array(N).keys()].map(i => ({ id: i })),
links: [...Array(N).keys()]
.filter(id => id)
.map(id => ({
source: id,
target: Math.round(Math.random() * (id - 1))
}))
}
}
},
}
</script>
<style lang="scss" scoped>
@media only screen and (max-width: 1200px){
#info, #indicator {
display: none !important;
}
}
.three-graph {
width: 1200px;
height: 750px;
// background-color: #000;
margin: 20px 0px;
// border: 2px #fff solid;
}
#indicator {
position: absolute;
// left: 50px;
// bottom: 30px;
left: 3vw;
bottom: 12vw;
text-align: left;
color: #f2f2f2;
font-size: 14px;
font-weight: bold;
& > div {
margin-bottom: 4px;
}
span {
display: inline-block;
width: 32px;
height: 16px;
position: relative;
top: 2px;
margin-right: 8px;
}
}
/*悬浮节点的info样式*/
/*悬浮节点的info样式*/
#info {
position: absolute;
bottom: 40px;
right: 30px;
width: 270px;
.node-card {
border: 1px solid #9faecf;
background-color: #00aeff6b;
color: #fff;
text-align: left;
// transition: background-color;
// transition-delay: .3s;
// transition-timing-function: ease;
.el-card__header {
border-bottom: 1px solid #50596d;
}
}
}
// #info {
// position: absolute;
// bottom: 40px;
// right: 30px;
// text-align: right;
// width: 270px;
// p {
// color: #fff;
// font-size: 12px;
// margin-top: 0;
// margin-bottom: 5px;
// }
// p span {
// color: #888;
// margin-right: 10px;
// }
// h4 {
// color: #fff;
// }
// }
</style>
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
return {
plugins: [vue()],
server: {
proxy: {
'/api': {
target: env.VITE_API_HOST,
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
headers: {
'Origin': env.VITE_API_HOST
}
}
}
}
}
})
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment