feat: 优化UI和功能,添加图标生成脚本
- 修复未匹配订单更新逻辑,添加去重机制避免重复赎回 - 优化跟单配置列表,移除订单菜单中的编辑选项 - 限制账户编辑功能,只允许编辑账户名称 - 优化Layout布局,将PC端图标移至标题下方,添加Telegram群链接 - 添加图标生成脚本到polymarket-demo目录 - 添加多个尺寸的favicon图标文件
This commit is contained in:
@@ -51,6 +51,9 @@ class PositionCheckService(
|
||||
// 记录已发送通知的仓位(避免重复推送)
|
||||
private val notifiedRedeemablePositions = ConcurrentHashMap<String, Long>() // "accountId_marketId_outcomeIndex" -> lastNotificationTime
|
||||
|
||||
// 记录已处理的赎回仓位(避免重复赎回)
|
||||
private val processedRedeemablePositions = ConcurrentHashMap<String, Long>() // "accountId_marketId_outcomeIndex" -> lastProcessTime
|
||||
|
||||
// 记录已发送提示的配置(避免重复推送)
|
||||
private val notifiedConfigs = ConcurrentHashMap<Long, Long>() // accountId/copyTradingId -> lastNotificationTime
|
||||
|
||||
@@ -139,6 +142,14 @@ class PositionCheckService(
|
||||
notifiedRedeemablePositions.remove(key)
|
||||
}
|
||||
|
||||
// 清理过期的已处理赎回仓位记录
|
||||
val expiredProcessed = processedRedeemablePositions.entries.filter { (_, timestamp) ->
|
||||
(now - timestamp) > expireTime
|
||||
}
|
||||
expiredProcessed.forEach { (key, _) ->
|
||||
processedRedeemablePositions.remove(key)
|
||||
}
|
||||
|
||||
// 清理过期的配置通知记录
|
||||
val expiredConfigs = notifiedConfigs.entries.filter { (_, timestamp) ->
|
||||
(now - timestamp) > expireTime
|
||||
@@ -147,8 +158,8 @@ class PositionCheckService(
|
||||
notifiedConfigs.remove(key)
|
||||
}
|
||||
|
||||
if (expiredPositions.isNotEmpty() || expiredConfigs.isNotEmpty()) {
|
||||
logger.debug("清理过期缓存: positions=${expiredPositions.size}, configs=${expiredConfigs.size}")
|
||||
if (expiredPositions.isNotEmpty() || expiredProcessed.isNotEmpty() || expiredConfigs.isNotEmpty()) {
|
||||
logger.debug("清理过期缓存: positions=${expiredPositions.size}, processed=${expiredProcessed.size}, configs=${expiredConfigs.size}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,9 +246,28 @@ class PositionCheckService(
|
||||
continue
|
||||
}
|
||||
|
||||
// 过滤掉已经处理过的仓位(去重,避免重复赎回)
|
||||
val now = System.currentTimeMillis()
|
||||
val positionsToRedeem = positions.filter { position ->
|
||||
val positionKey = "${accountId}_${position.marketId}_${position.outcomeIndex ?: 0}"
|
||||
val lastProcessed = processedRedeemablePositions[positionKey]
|
||||
// 如果最近30分钟内已经处理过,跳过(避免重复赎回)
|
||||
if (lastProcessed != null && (now - lastProcessed) < 1800000) { // 30分钟
|
||||
logger.debug("跳过已处理的赎回仓位: $positionKey (上次处理时间: ${lastProcessed})")
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
if (positionsToRedeem.isEmpty()) {
|
||||
logger.debug("所有仓位都已处理过,跳过赎回: accountId=$accountId")
|
||||
continue
|
||||
}
|
||||
|
||||
// 先执行赎回(不查找订单)
|
||||
val redeemRequest = com.wrbug.polymarketbot.dto.PositionRedeemRequest(
|
||||
positions = positions.map { position ->
|
||||
positions = positionsToRedeem.map { position ->
|
||||
com.wrbug.polymarketbot.dto.AccountRedeemPositionItem(
|
||||
accountId = accountId,
|
||||
marketId = position.marketId,
|
||||
@@ -250,10 +280,16 @@ class PositionCheckService(
|
||||
val redeemResult = accountService.redeemPositions(redeemRequest)
|
||||
redeemResult.fold(
|
||||
onSuccess = { response ->
|
||||
logger.info("自动赎回成功: accountId=$accountId, redeemedCount=${positions.size}, totalValue=${response.totalRedeemedValue}")
|
||||
logger.info("自动赎回成功: accountId=$accountId, redeemedCount=${positionsToRedeem.size}, totalValue=${response.totalRedeemedValue}")
|
||||
|
||||
// 记录已处理的仓位(避免重复赎回)
|
||||
for (position in positionsToRedeem) {
|
||||
val positionKey = "${accountId}_${position.marketId}_${position.outcomeIndex ?: 0}"
|
||||
processedRedeemablePositions[positionKey] = now
|
||||
}
|
||||
|
||||
// 赎回成功后,再查找订单并更新订单状态
|
||||
for (position in positions) {
|
||||
for (position in positionsToRedeem) {
|
||||
// 查找相同仓位的未卖出订单(remaining_quantity > 0)
|
||||
val unmatchedOrders = mutableListOf<CopyOrderTracking>()
|
||||
for (copyTrading in copyTradings) {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 320 B |
Binary file not shown.
|
After Width: | Height: | Size: 693 B |
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@@ -17,7 +17,8 @@ import {
|
||||
SettingOutlined,
|
||||
GithubOutlined,
|
||||
TwitterOutlined,
|
||||
CheckCircleOutlined
|
||||
CheckCircleOutlined,
|
||||
SendOutlined
|
||||
} from '@ant-design/icons'
|
||||
import type { MenuProps } from 'antd'
|
||||
import type { ReactNode } from 'react'
|
||||
@@ -197,12 +198,13 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
|
||||
size="normal"
|
||||
darkMode={true}
|
||||
/>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
|
||||
<a
|
||||
href="https://github.com/WrBug/PolyHermes"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ color: '#fff', fontSize: '18px' }}
|
||||
style={{ color: '#fff', fontSize: '16px', display: 'flex', alignItems: 'center' }}
|
||||
title="GitHub"
|
||||
>
|
||||
<GithubOutlined />
|
||||
</a>
|
||||
@@ -210,14 +212,24 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
|
||||
href="https://x.com/quant_tr"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ color: '#fff', fontSize: '18px' }}
|
||||
style={{ color: '#fff', fontSize: '16px', display: 'flex', alignItems: 'center' }}
|
||||
title="Twitter"
|
||||
>
|
||||
<TwitterOutlined />
|
||||
</a>
|
||||
<a
|
||||
href="https://t.me/+5BwdYvvvuf9iZGZl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ color: '#fff', fontSize: '16px', display: 'flex', alignItems: 'center' }}
|
||||
title="Telegram 交流群"
|
||||
>
|
||||
<SendOutlined />
|
||||
</a>
|
||||
<Button
|
||||
type="text"
|
||||
icon={<MenuOutlined />}
|
||||
style={{ color: '#fff' }}
|
||||
style={{ color: '#fff', marginLeft: '4px' }}
|
||||
onClick={() => setMobileMenuOpen(true)}
|
||||
/>
|
||||
</div>
|
||||
@@ -265,23 +277,30 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
|
||||
}}
|
||||
>
|
||||
<div style={{
|
||||
height: '64px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: '0 16px',
|
||||
padding: '16px',
|
||||
color: '#fff',
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
flexShrink: 0
|
||||
flexShrink: 0,
|
||||
borderBottom: '1px solid rgba(255, 255, 255, 0.1)'
|
||||
}}>
|
||||
<span>PolyHermes</span>
|
||||
<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
|
||||
<div style={{
|
||||
fontSize: '18px',
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '12px',
|
||||
textAlign: 'center'
|
||||
}}>
|
||||
PolyHermes
|
||||
</div>
|
||||
<div style={{
|
||||
display: 'flex',
|
||||
gap: '12px',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}}>
|
||||
<a
|
||||
href="https://github.com/WrBug/PolyHermes"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ color: '#fff', fontSize: '16px' }}
|
||||
style={{ color: '#fff', fontSize: '18px', display: 'flex', alignItems: 'center' }}
|
||||
title="GitHub"
|
||||
>
|
||||
<GithubOutlined />
|
||||
@@ -290,11 +309,20 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
|
||||
href="https://x.com/quant_tr"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ color: '#fff', fontSize: '16px' }}
|
||||
style={{ color: '#fff', fontSize: '18px', display: 'flex', alignItems: 'center' }}
|
||||
title="Twitter"
|
||||
>
|
||||
<TwitterOutlined />
|
||||
</a>
|
||||
<a
|
||||
href="https://t.me/+5BwdYvvvuf9iZGZl"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
style={{ color: '#fff', fontSize: '18px', display: 'flex', alignItems: 'center' }}
|
||||
title="Telegram 交流群"
|
||||
>
|
||||
<SendOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<Menu
|
||||
@@ -305,7 +333,7 @@ const Layout: React.FC<LayoutProps> = ({ children }) => {
|
||||
items={menuItems}
|
||||
onClick={handleMenuClick}
|
||||
style={{
|
||||
height: 'calc(100vh - 64px)',
|
||||
height: 'calc(100vh - 100px)',
|
||||
borderRight: 0,
|
||||
overflowY: 'auto'
|
||||
}}
|
||||
|
||||
@@ -72,23 +72,12 @@ const AccountDetail: React.FC = () => {
|
||||
|
||||
setEditLoading(true)
|
||||
try {
|
||||
// 构建更新请求,空字符串转换为 undefined(不修改)
|
||||
// 构建更新请求,只支持编辑账户名称
|
||||
const updateData: any = {
|
||||
accountId: account.id,
|
||||
accountName: values.accountName || undefined,
|
||||
}
|
||||
|
||||
// 只有非空字符串才更新 API 凭证
|
||||
if (values.apiKey && values.apiKey.trim()) {
|
||||
updateData.apiKey = values.apiKey.trim()
|
||||
}
|
||||
if (values.apiSecret && values.apiSecret.trim()) {
|
||||
updateData.apiSecret = values.apiSecret.trim()
|
||||
}
|
||||
if (values.apiPassphrase && values.apiPassphrase.trim()) {
|
||||
updateData.apiPassphrase = values.apiPassphrase.trim()
|
||||
}
|
||||
|
||||
await updateAccount(updateData)
|
||||
|
||||
message.success(t('account.updateSuccess'))
|
||||
@@ -335,42 +324,18 @@ const AccountDetail: React.FC = () => {
|
||||
size={isMobile ? 'middle' : 'large'}
|
||||
>
|
||||
<Alert
|
||||
message={t('account.editTip')}
|
||||
description={t('account.editTipDesc')}
|
||||
message={t('account.editTip') || '编辑账户'}
|
||||
description={t('account.editTipDesc') || '只能编辑账户名称,API 凭证需要通过导入账户功能更新。'}
|
||||
type="info"
|
||||
showIcon
|
||||
style={{ marginBottom: '24px' }}
|
||||
/>
|
||||
|
||||
<Form.Item
|
||||
label={t('account.accountName')}
|
||||
label={t('account.accountName') || '账户名称'}
|
||||
name="accountName"
|
||||
>
|
||||
<Input placeholder={t('account.accountNamePlaceholder')} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('account.apiKey')}
|
||||
name="apiKey"
|
||||
help={t('account.leaveEmptyToNotModify')}
|
||||
>
|
||||
<Input.Password placeholder={t('account.leaveEmptyToNotModify')} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('account.apiSecret')}
|
||||
name="apiSecret"
|
||||
help={t('account.leaveEmptyToNotModify')}
|
||||
>
|
||||
<Input.Password placeholder={t('account.leaveEmptyToNotModify')} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('account.apiPassphrase')}
|
||||
name="apiPassphrase"
|
||||
help={t('account.leaveEmptyToNotModify')}
|
||||
>
|
||||
<Input.Password placeholder={t('account.leaveEmptyToNotModify')} />
|
||||
<Input placeholder={t('account.accountNamePlaceholder') || '请输入账户名称(可选)'} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
|
||||
@@ -171,23 +171,12 @@ const AccountList: React.FC = () => {
|
||||
|
||||
setEditLoading(true)
|
||||
try {
|
||||
// 构建更新请求,空字符串转换为 undefined(不修改)
|
||||
// 构建更新请求,只支持编辑账户名称
|
||||
const updateData: any = {
|
||||
accountId: editAccount.id,
|
||||
accountName: values.accountName || undefined
|
||||
}
|
||||
|
||||
// 只有非空字符串才更新 API 凭证
|
||||
if (values.apiKey && values.apiKey.trim()) {
|
||||
updateData.apiKey = values.apiKey.trim()
|
||||
}
|
||||
if (values.apiSecret && values.apiSecret.trim()) {
|
||||
updateData.apiSecret = values.apiSecret.trim()
|
||||
}
|
||||
if (values.apiPassphrase && values.apiPassphrase.trim()) {
|
||||
updateData.apiPassphrase = values.apiPassphrase.trim()
|
||||
}
|
||||
|
||||
await updateAccount(updateData)
|
||||
|
||||
message.success(t('accountList.updateSuccess'))
|
||||
@@ -778,42 +767,18 @@ const AccountList: React.FC = () => {
|
||||
size={isMobile ? 'middle' : 'large'}
|
||||
>
|
||||
<Alert
|
||||
message={t('accountList.editTip')}
|
||||
description={t('accountList.editTipDesc')}
|
||||
message={t('accountList.editTip') || '编辑账户'}
|
||||
description={t('accountList.editTipDesc') || '只能编辑账户名称,API 凭证需要通过导入账户功能更新。'}
|
||||
type="info"
|
||||
showIcon
|
||||
style={{ marginBottom: '24px' }}
|
||||
/>
|
||||
|
||||
<Form.Item
|
||||
label={t('accountList.accountName')}
|
||||
label={t('accountList.accountName') || '账户名称'}
|
||||
name="accountName"
|
||||
>
|
||||
<Input placeholder={t('accountList.accountNamePlaceholder')} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('accountList.apiKey')}
|
||||
name="apiKey"
|
||||
help={t('accountList.leaveEmptyToNotModify')}
|
||||
>
|
||||
<Input.Password placeholder={t('accountList.leaveEmptyToNotModify')} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('accountList.apiSecret')}
|
||||
name="apiSecret"
|
||||
help={t('accountList.leaveEmptyToNotModify')}
|
||||
>
|
||||
<Input.Password placeholder={t('accountList.leaveEmptyToNotModify')} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label={t('accountList.apiPassphrase')}
|
||||
name="apiPassphrase"
|
||||
help={t('accountList.leaveEmptyToNotModify')}
|
||||
>
|
||||
<Input.Password placeholder={t('accountList.leaveEmptyToNotModify')} />
|
||||
<Input placeholder={t('accountList.accountNamePlaceholder') || '请输入账户名称(可选)'} />
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
|
||||
@@ -265,15 +265,6 @@ const CopyTradingList: React.FC = () => {
|
||||
fixed: 'right' as const,
|
||||
render: (_: any, record: CopyTrading) => {
|
||||
const menuItems: MenuProps['items'] = [
|
||||
{
|
||||
key: 'edit',
|
||||
label: t('common.edit') || '编辑',
|
||||
icon: <EditOutlined />,
|
||||
onClick: () => navigate(`/copy-trading/edit/${record.id}`)
|
||||
},
|
||||
{
|
||||
type: 'divider'
|
||||
},
|
||||
{
|
||||
key: 'buyOrders',
|
||||
label: t('copyTradingList.buyOrders') || '买入订单',
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
Generated
+437
@@ -14,6 +14,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.18",
|
||||
"canvas": "^3.2.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.3"
|
||||
}
|
||||
@@ -957,11 +958,42 @@
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/bech32": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz",
|
||||
"integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ=="
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/bn.js": {
|
||||
"version": "4.12.2",
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz",
|
||||
@@ -977,6 +1009,30 @@
|
||||
"resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-2.1.1.tgz",
|
||||
"integrity": "sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg=="
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
@@ -989,6 +1045,26 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/canvas": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.0.tgz",
|
||||
"integrity": "sha512-jk0GxrLtUEmW/TmFsk2WghvgHe8B0pxGilqCL21y8lHkPUGa6FTsnCNtHPOzT8O3y+N+m3espawV80bbBlgfTA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"node-addon-api": "^7.0.0",
|
||||
"prebuild-install": "^7.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.12.0 || >= 20.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
|
||||
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
@@ -1006,6 +1082,30 @@
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-extend": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
|
||||
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -1014,6 +1114,15 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
@@ -1050,6 +1159,15 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
||||
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
@@ -1162,6 +1280,15 @@
|
||||
"npm": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/expand-template": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
|
||||
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.11",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
|
||||
@@ -1196,6 +1323,12 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-constants": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
|
||||
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
@@ -1239,6 +1372,12 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||
@@ -1305,11 +1444,37 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/ini": {
|
||||
"version": "1.3.8",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
|
||||
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/is-hex-prefixed": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
|
||||
@@ -1362,6 +1527,18 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/minimalistic-assert": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
@@ -1372,16 +1549,215 @@
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
|
||||
"integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"dev": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/mkdirp-classic": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
|
||||
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/napi-build-utils": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.85.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.85.0.tgz",
|
||||
"integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
|
||||
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/prebuild-install": {
|
||||
"version": "7.1.3",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
|
||||
"integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.0",
|
||||
"expand-template": "^2.0.3",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mkdirp-classic": "^0.5.3",
|
||||
"napi-build-utils": "^2.0.0",
|
||||
"node-abi": "^3.3.0",
|
||||
"pump": "^3.0.0",
|
||||
"rc": "^1.2.7",
|
||||
"simple-get": "^4.0.0",
|
||||
"tar-fs": "^2.0.0",
|
||||
"tunnel-agent": "^0.6.0"
|
||||
},
|
||||
"bin": {
|
||||
"prebuild-install": "bin.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz",
|
||||
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/rc": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
|
||||
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"deep-extend": "^0.6.0",
|
||||
"ini": "~1.3.0",
|
||||
"minimist": "^1.2.0",
|
||||
"strip-json-comments": "~2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"rc": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/scrypt-js": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
|
||||
"integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA=="
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-concat": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
|
||||
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/simple-get": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
|
||||
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"decompress-response": "^6.0.0",
|
||||
"once": "^1.3.1",
|
||||
"simple-concat": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-hex-prefix": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
|
||||
@@ -1394,6 +1770,43 @@
|
||||
"npm": ">=3"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
|
||||
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-fs": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz",
|
||||
"integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"chownr": "^1.1.1",
|
||||
"mkdirp-classic": "^0.5.2",
|
||||
"pump": "^3.0.0",
|
||||
"tar-stream": "^2.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/tar-stream": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
|
||||
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"bl": "^4.0.3",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fs-constants": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node": {
|
||||
"version": "10.9.2",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
||||
@@ -1442,6 +1855,18 @@
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||
},
|
||||
"node_modules/tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/tweetnacl": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
|
||||
@@ -1470,12 +1895,24 @@
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/v8-compile-cache-lib": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
||||
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ws": {
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"scripts": {
|
||||
"test": "ts-node src/createOrder.ts",
|
||||
"build": "tsc",
|
||||
"start": "node dist/createOrder.js"
|
||||
"start": "node dist/createOrder.js",
|
||||
"generate-icon": "node scripts/generate-icon.js"
|
||||
},
|
||||
"keywords": [
|
||||
"polymarket",
|
||||
@@ -21,8 +22,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.7.18",
|
||||
"canvas": "^3.2.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
const { createCanvas } = require('canvas');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
// 创建 512x512 的画布
|
||||
const canvas = createCanvas(512, 512);
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// 设置背景色(标题背景色 #001529)
|
||||
ctx.fillStyle = '#001529';
|
||||
ctx.fillRect(0, 0, 512, 512);
|
||||
|
||||
// 设置图标颜色(深色背景使用较亮的颜色)
|
||||
const gradientColors = {
|
||||
start: '#69c0ff',
|
||||
end: '#b37feb'
|
||||
};
|
||||
|
||||
// 创建渐变
|
||||
const gradient = ctx.createLinearGradient(0, 0, 512, 512);
|
||||
gradient.addColorStop(0, gradientColors.start);
|
||||
gradient.addColorStop(1, gradientColors.end);
|
||||
|
||||
// 计算缩放比例(原始 viewBox 是 64x64,需要缩放到 512x512)
|
||||
const scale = 512 / 64;
|
||||
const centerX = 256;
|
||||
const centerY = 256;
|
||||
|
||||
// 保存当前状态
|
||||
ctx.save();
|
||||
|
||||
// 移动到中心并缩放
|
||||
ctx.translate(centerX, centerY);
|
||||
ctx.scale(scale, scale);
|
||||
ctx.translate(-32, -32); // 偏移到原点
|
||||
|
||||
// 绘制左侧箭头(指向中心)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(16, 32);
|
||||
ctx.lineTo(8, 24);
|
||||
ctx.lineTo(8, 40);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
|
||||
// 绘制中心连接线
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(20, 32);
|
||||
ctx.lineTo(44, 32);
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.lineWidth = 3 / scale; // 调整线宽
|
||||
ctx.lineCap = 'round';
|
||||
ctx.stroke();
|
||||
|
||||
// 绘制右侧箭头(指向中心)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(48, 32);
|
||||
ctx.lineTo(56, 24);
|
||||
ctx.lineTo(56, 40);
|
||||
ctx.closePath();
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
|
||||
// 绘制中心圆点
|
||||
ctx.beginPath();
|
||||
ctx.arc(32, 32, 5, 0, Math.PI * 2);
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fill();
|
||||
|
||||
// 绘制装饰性数据流弧线(上方)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(20, 20);
|
||||
ctx.quadraticCurveTo(32, 14, 44, 20);
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.lineWidth = 2 / scale;
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.stroke();
|
||||
|
||||
// 绘制装饰性数据流弧线(下方)
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(20, 44);
|
||||
ctx.quadraticCurveTo(32, 50, 44, 44);
|
||||
ctx.strokeStyle = gradient;
|
||||
ctx.lineWidth = 2 / scale;
|
||||
ctx.globalAlpha = 0.5;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.stroke();
|
||||
|
||||
// 恢复状态
|
||||
ctx.restore();
|
||||
|
||||
// 保存为 PNG(输出到当前目录)
|
||||
const outputPath = path.join(__dirname, '../icon-512x512.png');
|
||||
// 确保输出目录存在
|
||||
const outputDir = path.dirname(outputPath);
|
||||
if (!fs.existsSync(outputDir)) {
|
||||
fs.mkdirSync(outputDir, { recursive: true });
|
||||
}
|
||||
|
||||
const buffer = canvas.toBuffer('image/png');
|
||||
fs.writeFileSync(outputPath, buffer);
|
||||
|
||||
console.log(`✅ 图标已生成: ${outputPath}`);
|
||||
console.log(` 尺寸: 512x512 像素`);
|
||||
console.log(` 背景色: #001529`);
|
||||
|
||||
Reference in New Issue
Block a user