chore: remove legacy deepagens-static site (keep deepagens-new only)

This commit is contained in:
王喆 2025-11-03 14:35:31 +08:00
parent 9d9a8d0120
commit 7c0c5b44a2
879 changed files with 147339 additions and 735 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@ -1,4 +1,8 @@
{
"/Users/wangzhe/CodeBuddy/20251021144130/deepagens-static": "ac5416bb0e61498cab9a8ebe523e0c8a",
"/Users/wangzhe/CodeBuddy/20251021144130/deepagens-new": "f7615053c5184cd2b9023fe45bfc9773"
"/Users/wangzhe/CodeBuddy/20251021144130/deepagens-new": "f7615053c5184cd2b9023fe45bfc9773",
"/Users/wangzhe/CodeBuddy/20251021144130/doubao-asr-demo": "6b608025438f495aa26a2a6f92604ca1",
"/Users/wangzhe/CodeBuddy/20251021144130/legacy-deepagens/deepagens-static": "31534ea7028c4b10a50d8a2dabc509ac",
"/Users/wangzhe/CodeBuddy/20251021144130/legacy-deepagens": "9c2045b4745b40c483cf544342172280",
"/Users/wangzhe/CodeBuddy/20251021144130/legacy-deepagens/deepagens-new": "e54571aed7f34d71b57b432903356a46"
}

1
.codebuddy/status.log Normal file
View File

@ -0,0 +1 @@
我准备为task1创建一个独立的转写页面骨架。

1
.codebuddy/todo.json Normal file
View File

@ -0,0 +1 @@
{"todo_items":[],"version":1}

0
TODO Normal file
View File

View File

@ -1,40 +0,0 @@
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><title>咨询与联系|深度云海</title><link rel="stylesheet" href="styles.css" /></head><body>
<header class="nav"><div class="container nav-inner"><div class="brand"><img class="brand-logo" src="logo.png" alt="深度云海"/><div class="brand-name">深度云海Deepagens</div></div><nav>
<a href="index.html">首页</a>
<a href="services/raas-platform/">服务</a>
<a href="cases.html">客户案例</a>
<a href="blog.html">行业洞察</a>
<a href="about.html">关于我们</a>
<a class="btn btn-primary" href="contact.html">免费咨询</a>
</nav></div></header>
<section class="hero"><div class="container"><h1>获取定制方案</h1><p class="sub">平均响应2小时专家1对1沟通。</p><div class="hero-visual"><img src="assets/contact-hero.svg" alt="联系示意图" style="width:100%;max-width:640px"></div></div></section>
<section class="contact"><div class="container">
<form id="contact-form" class="form">
<div class="grid-2">
<label>姓名<input type="text" name="name" required /></label>
<label>公司<input type="text" name="company" /></label>
</div>
<div class="grid-2">
<label>邮箱<input type="email" name="email" required /></label>
<label>手机号<input type="tel" name="phone" /></label>
</div>
<label>业务类型
<select name="type">
<option>生活服务</option>
<option>智能制造</option>
<option>新能源</option>
<option>医疗健康</option>
<option>其他</option>
</select>
</label>
<label>需求描述<textarea name="need" rows="4" placeholder="请简要描述您的需求…"></textarea></label>
<div class="actions">
<button class="btn btn-primary" type="submit">提交</button>
<span id="form-msg" class="muted"></span>
</div>
</form>
<div class="card" style="margin-top:16px"><p class="sub">致电咨询133-5928-2414工作日 9:00-18:00</p></div>
</div></section>
<script src="script.js"></script>
</body></html>

View File

@ -1,38 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>关于我们深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
<a href="pricing.html">定价</a>
<a href="resources.html">资源库</a>
<a href="about.html">关于我们</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>关于深度未来</h1>
<p class="sub">使命让AI主动推荐你。愿景构建可被机器与人同时理解的品牌资产。</p>
</div>
</section>
<section class="section">
<div class="container grid-3">
<div class="card"><h3>里程碑</h3><p>2025年发布AI搜索全链路方案首批客户营收破百万。</p></div>
<div class="card"><h3>团队</h3><p>AI工程、增长、产品、市场的跨职能团队。</p></div>
<div class="card"><h3>资质</h3><p>专利权威信号点埋入技术合规GDPR/CCPA。</p></div>
</div>
</section>
</body>
</html>

View File

@ -1,38 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>博客深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
<a href="pricing.html">定价</a>
<a href="resources.html">资源库</a>
<a href="blog.html">博客</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>AI营销洞察</h1>
<p class="sub">围绕“AI搜索优化”“GEO营销”“AI建站系统”“智能体客服”的思想领导力内容。</p>
</div>
</section>
<section class="section">
<div class="container grid-3">
<div class="card"><h3>支柱页AI搜索时代企业获客终极指南</h3><p>8000字长文占位。</p></div>
<div class="card"><h3>专题GEO营销方法论</h3><p>互链至支柱页。</p></div>
<div class="card"><h3>专题:智能体客服转化提升</h3><p>实操案例与数据。</p></div>
</div>
</section>
</body>
</html>

View File

@ -1,76 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>客户案例深度未来Deepagens</title>
<meta name="description" content="行业筛选与标杆案例:制造业、零售业、生活服务(途悠居集团)。展示挑战-方案-结果与KPI。" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>客户案例</h1>
<p class="sub">按行业查看成功故事与量化结果,支持下载 PDF 摘要与客户证言视频嵌入。</p>
<div class="cta">
<a class="btn btn-primary" href="solutions.html">了解方案</a>
<a class="btn btn-secondary" href="index.html#contact">联系销售</a>
</div>
</div>
</section>
<section class="cases">
<div class="container">
<h2>行业筛选</h2>
<div class="grid-3">
<div class="card"><h3>制造业</h3><p>质量检测与售后提升。</p></div>
<div class="card"><h3>零售业</h3><p>AI搜索咨询量提升 190%。</p></div>
<div class="card"><h3>生活服务</h3><p>途悠居集团GEO优化后咨询量 +200%。</p></div>
</div>
</div>
</section>
<section class="cases">
<div class="container">
<h2>精选案例</h2>
<div class="grid-3">
<div class="case-card">
<div class="case-thumb"></div>
<h3>豫信新能源</h3>
<p>挑战未被AI推荐导致月流失500+商机</p>
<p>方案AI建站 + 200个蒸馏问答</p>
<p>结果品牌AI提及率 5% → 62%转化成本下降35%</p>
</div>
<div class="case-card">
<div class="case-thumb"></div>
<h3>途悠居集团</h3>
<p>行业:生活服务</p>
<p>结果GEO优化后咨询量 +200%</p>
</div>
<div class="case-card">
<div class="case-thumb"></div>
<h3>某零售品牌</h3>
<p>AI搜索咨询量提升 190%</p>
</div>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<div>© 2025 深度未来Deepagens<a href="#" class="muted">隐私政策</a><a href="#" class="muted">使用条款</a><a href="#" class="muted">GDPR声明</a></div>
</div>
</footer>
</body>
</html>

View File

@ -1,51 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>联系我们深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
<a href="pricing.html">定价</a>
<a href="resources.html">资源库</a>
<a href="about.html">关于我们</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>联系与获取线索</h1>
<p class="sub">请填写表单,我们将在一个工作日内联系您。</p>
</div>
</section>
<section class="contact">
<div class="container">
<form id="contact-form" class="form">
<div class="grid-2">
<label>姓名<input type="text" name="name" required /></label>
<label>邮箱<input type="email" name="email" required /></label>
</div>
<div class="grid-2">
<label>公司<input type="text" name="company" /></label>
<label>手机号<input type="tel" name="phone" /></label>
</div>
<label>需求描述<textarea name="need" rows="4" placeholder="请简要描述您的需求…"></textarea></label>
<div class="actions">
<button class="btn btn-primary" type="submit">提交</button>
<span id="form-msg" class="muted"></span>
</div>
</form>
</div>
</section>
<script src="script.js"></script>
</body>
</html>

View File

@ -1,36 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>开发者中心深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
<a href="developers.html">开发者中心</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>开发者中心</h1>
<p class="sub">API/SDK文档占位快速开始、认证、示例请求、Webhook、错误码。</p>
</div>
</section>
<section class="section">
<div class="container grid-3">
<div class="card"><h3>快速开始</h3><p>生成密钥、初始化SDK。</p></div>
<div class="card"><h3>示例</h3><p>Node/Python调用示例。</p></div>
<div class="card"><h3>状态与变更</h3><p>版本更新与状态页占位。</p></div>
</div>
</section>
</body>
</html>

View File

@ -1,132 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>深度未来Deepagens— AI搜索营销全链路方案</title>
<meta name="description" content="让AI主动推荐你。AI搜索时代的全链路营销闭环7天完成AI建站上线部分客户获客成本下降40%。" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
<a href="pricing.html">定价</a>
<a href="resources.html">资源库</a>
<a href="blog.html">博客</a>
<a href="about.html">关于我们</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>AI搜索时代你的品牌必须被看见</h1>
<p class="sub">深度未来通过AI搜索全链路营销闭环帮助中小企业平均7天完成AI建站上线部分客户获客成本下降40%(详见案例)。</p>
<div class="cta">
<a class="btn btn-primary" href="solutions.html">预约演示</a>
<a class="btn btn-secondary" href="resources.html">下载白皮书</a>
<a class="btn btn-ghost" href="pricing.html">免费体验 Lite</a>
</div>
<div class="hero-visual">
<div class="globe"></div>
</div>
</div>
</section>
<section id="selling" class="selling">
<div class="container grid-3">
<div class="card">
<h3>10分钟AI建站</h3>
<p>专利Schema预埋技术自动生成可被AI理解的品牌资产。</p>
</div>
<div class="card">
<h3>实时GEO监控</h3>
<p>跨平台品牌提及率追踪,看板实时洞察与预警。</p>
</div>
<div class="card">
<h3>智能体销售转化</h3>
<p>92.7%情感识别准确率,蒸馏问答驱动转化闭环。</p>
</div>
</div>
</section>
<section class="logos section">
<div class="container">
<p class="muted">受信任于行业头部客户</p>
<div class="logo-wall">
<div class="logo-item">爱尔眼科</div>
<div class="logo-item">豫信新能源</div>
<div class="logo-item">锐之旗</div>
<div class="logo-item">途悠居集团</div>
<div class="logo-item">示例客户A</div>
<div class="logo-item">示例客户B</div>
</div>
</div>
</section>
<section class="pricing section">
<div class="container">
<h2>定价中心</h2>
<div class="grid-2">
<div class="price-card">
<h3>标准版</h3>
<ul>
<li>AI建站</li>
<li>基础GEO监控</li>
<li>智能体客服FAQ限定</li>
<li>邮件支持</li>
</ul>
<a class="btn btn-secondary" href="pricing.html">开始试用</a>
</div>
<div class="price-card featured">
<h3>企业版</h3>
<ul>
<li>专利Schema注入</li>
<li>跨平台提及率看板</li>
<li>高级智能体销售</li>
<li>企业SLA与私有化部署支持</li>
</ul>
<a class="btn btn-primary" href="pricing.html">联系销售</a>
</div>
</div>
</div>
</section>
<section class="resources section">
<div class="container">
<h2>资源库</h2>
<div class="grid-3">
<div class="card">
<h3>AI搜索营销白皮书</h3>
<p>下载需要填写基本信息。</p>
<a class="btn btn-outline" href="resources.html">下载白皮书</a>
</div>
<div class="card">
<h3>产品手册</h3>
<p>PDF与PPT模板。</p>
<a class="btn btn-outline" href="resources.html">下载手册</a>
</div>
<div class="card">
<h3>开发者文档</h3>
<p>API与SDK占位。</p>
<a class="btn btn-outline" href="developers.html">查看文档</a>
</div>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<div>© 2025 深度未来Deepagens<a href="privacy.html" class="muted">隐私政策</a><a href="privacy.html" class="muted">使用条款</a><a href="privacy.html" class="muted">GDPR声明</a></div>
</div>
</footer>
<script src="script.js"></script>
</body>
</html>

View File

@ -1,35 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>媒体中心深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="media.html">媒体中心</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>媒体与新闻</h1>
<p class="sub">媒体报道、新闻稿与品牌素材下载。</p>
</div>
</section>
<section class="section">
<div class="container grid-3">
<div class="card"><h3>新闻稿</h3><p>新品发布与案例报道。</p></div>
<div class="card"><h3>媒体报道</h3><p>第三方媒体链接。</p></div>
<div class="card"><h3>品牌素材</h3><p>Logo与使用规范。</p></div>
</div>
</section>
</body>
</html>

View File

@ -1,55 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>定价中心深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
<a href="pricing.html">定价</a>
<a href="resources.html">资源库</a>
<a href="about.html">关于我们</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>定价与方案</h1>
<p class="sub">为中小企业到大型集团提供可扩展的AI搜索营销解决方案。</p>
</div>
</section>
<section class="pricing">
<div class="container grid-2">
<div class="price-card">
<h3>标准版</h3>
<ul>
<li>AI建站</li>
<li>基础GEO监控</li>
<li>智能体客服FAQ限定</li>
<li>邮件支持</li>
</ul>
<a class="btn btn-secondary" href="contact.html">开始试用</a>
</div>
<div class="price-card featured">
<h3>企业版</h3>
<ul>
<li>专利Schema注入</li>
<li>跨平台提及率看板</li>
<li>高级智能体销售</li>
<li>企业SLA与私有化部署支持</li>
</ul>
<a class="btn btn-primary" href="contact.html">联系销售</a>
</div>
</div>
</section>
</body>
</html>

View File

@ -1,35 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>隐私与条款深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="privacy.html">隐私政策</a>
<a href="privacy.html">使用条款</a>
<a href="privacy.html">GDPR声明</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>隐私与合规</h1>
<p class="sub">占位GDPR/CCPA合规、Cookie策略与用户权利说明。</p>
</div>
</section>
<section class="section">
<div class="container">
<div class="card"><h3>隐私政策</h3><p>数据收集、使用与存储。</p></div>
<div class="card"><h3>使用条款</h3><p>服务使用的规则与限制。</p></div>
<div class="card"><h3>GDPR声明</h3><p>数据主体权利与请求方式。</p></div>
</div>
</section>
</body>
</html>

View File

@ -1,38 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>资源库深度未来Deepagens</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
<a href="pricing.html">定价</a>
<a href="resources.html">资源库</a>
<a href="about.html">关于我们</a>
<a href="contact.html" class="btn btn-outline">联系我们</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>资源中心</h1>
<p class="sub">白皮书、产品手册、开发文档等,支持下载与演示。</p>
</div>
</section>
<section class="resources">
<div class="container grid-3">
<div class="card"><h3>AI搜索营销白皮书</h3><p>填写信息后获取下载链接。</p></div>
<div class="card"><h3>产品手册</h3><p>PDF/PPT模板。</p></div>
<div class="card"><h3>开发者文档</h3><p>API与SDK占位。</p></div>
</div>
</section>
</body>
</html>

View File

@ -1,8 +0,0 @@
document.getElementById('contact-form').addEventListener('submit', function (e) {
e.preventDefault();
const btn = this.querySelector('button[type="submit"]');
btn.disabled = true;
const msg = document.getElementById('form-msg');
msg.textContent = '感谢提交!我们将尽快联系您。';
setTimeout(() => { btn.disabled = false; msg.textContent = ''; }, 3000);
});

View File

@ -1,74 +0,0 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>解决方案深度未来Deepagens</title>
<meta name="description" content="AI搜索导致自然流量下降深度未来以四层技术栈实现从数据到转化的闭环数据采集 → AI分析 → 内容执行 → 追踪反馈。" />
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<header class="nav">
<div class="container nav-inner">
<div class="logo">Deepagens</div>
<nav>
<a href="index.html">首页</a>
<a href="solutions.html">解决方案</a>
<a href="cases.html">成功案例</a>
</nav>
</div>
</header>
<section class="hero">
<div class="container">
<h1>AI搜索全链路解决方案</h1>
<p class="sub">问题场景AI搜索导致自然流量下降40%(参考行业报告)。我们以四层技术栈实现从数据到转化的闭环:数据采集 → AI分析 → 内容执行 → 追踪反馈。</p>
<div class="cta">
<a class="btn btn-primary" href="#trial">免费体验 Lite 版</a>
<a class="btn btn-secondary" href="cases.html">查看客户案例</a>
</div>
</div>
</section>
<section class="solutions">
<div class="container">
<h2>技术架构</h2>
<div class="grid-4 grid-3">
<div class="card"><h3>数据采集</h3><p>跨平台抓取品牌相关问答与提及,构建知识库。</p></div>
<div class="card"><h3>AI分析</h3><p>蒸馏问答与情感识别,提取权威信号点。</p></div>
<div class="card"><h3>内容执行</h3><p>AI一键建站专利Schema预埋生成结构化资产。</p></div>
<div class="card"><h3>追踪反馈</h3><p>GEO监控看板品牌提及率与转化闭环。</p></div>
</div>
</div>
</section>
<section class="solutions">
<div class="container">
<h2>功能模块</h2>
<div class="grid-3">
<div class="card">
<h3>AI一键建站</h3>
<p>结构化资产生成Schema预埋专利</p>
</div>
<div class="card">
<h3>GEO监控看板</h3>
<p>品牌提及率跨平台追踪,异常提醒。</p>
</div>
<div class="card">
<h3>智能体客服</h3>
<p>高准确情感识别与蒸馏问答,促进成交。</p>
</div>
</div>
<div class="cta center" id="trial">
<a class="btn btn-primary" href="cases.html">预约演示</a>
</div>
</div>
</section>
<footer class="footer">
<div class="container">
<div>© 2025 深度未来Deepagens<a href="#" class="muted">隐私政策</a><a href="#" class="muted">使用条款</a><a href="#" class="muted">GDPR声明</a></div>
</div>
</footer>
</body>
</html>

View File

@ -1,59 +0,0 @@
* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, PingFang SC, Helvetica, Arial, sans-serif; color: #e6f2ff; background: #0b1220; }
:root {
--bg-start: #07121f; /* 深色 */
--bg-end: #0d2137; /* 渐变过渡 */
--accent-1: #1fb6ff; /* 湖蓝主色 */
--accent-2: #00c9a7; /* 湖蓝-青色过渡 */
--text-primary: #e6f2ff;
--text-muted: #a8c0d8;
--card-bg: #0f1a2b;
--card-border: #16324a;
--btn-ghost: #a8c0d8;
}
.container { max-width: 1100px; margin: 0 auto; padding: 0 20px; }
.nav { position: sticky; top: 0; background: rgba(7,18,31,0.65); backdrop-filter: saturate(180%) blur(10px); border-bottom: 1px solid var(--card-border); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 64px; }
.nav a { margin-left: 16px; color: var(--text-muted); text-decoration: none; }
.nav a:hover { color: var(--text-primary); }
.logo { font-weight: 700; letter-spacing: 0.5px; color: var(--text-primary); }
.btn { display: inline-block; padding: 10px 16px; border-radius: 8px; text-decoration: none; font-weight: 600; }
.btn-primary { background: linear-gradient(90deg, var(--accent-1), var(--accent-2)); color: #04121f; }
.btn-secondary { background: #0c2a43; color: var(--text-primary); border: 1px solid var(--card-border); }
.btn-outline { border: 1px solid var(--card-border); color: var(--text-primary); }
.btn-ghost { color: var(--btn-ghost); }
.center { text-align: center; }
.hero { padding: 80px 0 40px; background: radial-gradient(1200px 600px at 30% -20%, rgba(31,182,255,0.25), rgba(0,201,167,0.18) 40%, rgba(11,18,32,0) 75%), linear-gradient(180deg, var(--bg-start), var(--bg-end)); }
.hero h1 { font-size: 40px; margin: 0 0 12px; color: var(--text-primary); }
.hero .sub { color: var(--text-muted); max-width: 720px; }
.cta { margin: 20px 0; display: flex; gap: 12px; flex-wrap: wrap; }
.hero-visual { margin-top: 28px; height: 240px; display: flex; align-items: center; }
.globe { width: 240px; height: 240px; border-radius: 50%; background: radial-gradient(circle at 30% 30%, var(--accent-2), var(--accent-1) 60%, #0b1220 100%); box-shadow: 0 10px 30px rgba(2,6,23,0.35); animation: spin 12s linear infinite; }
@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
.section { padding: 40px 0; background: linear-gradient(180deg, var(--bg-start), var(--bg-end)); }
.selling { padding: 40px 0; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }
.card { padding: 16px; border: 1px solid var(--card-border); border-radius: 12px; background: var(--card-bg); }
.card h3 { color: var(--text-primary); }
.card p { color: var(--text-muted); }
.logo-wall { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; margin-top: 10px; }
.logo-item { border: 1px dashed var(--card-border); border-radius: 10px; padding: 10px; text-align: center; color: var(--text-muted); background: #0a1929; }
.solutions, .cases, .pricing, .resources, .contact { padding: 40px 0; }
.section h2, .solutions h2, .cases h2, .pricing h2, .resources h2, .contact h2 { color: var(--text-primary); }
.case-card { border: 1px solid var(--card-border); border-radius: 12px; padding: 16px; background: var(--card-bg); }
.case-thumb { height: 120px; background: #0a1929; border-radius: 8px; margin-bottom: 10px; }
.price-card { border: 1px solid var(--card-border); border-radius: 12px; padding: 16px; background: var(--card-bg); }
.price-card.featured { border-color: var(--accent-1); box-shadow: 0 8px 24px rgba(31,182,255,0.2); }
.form label { display: flex; flex-direction: column; gap: 6px; color: var(--text-muted); }
.form input, .form textarea { padding: 10px; border: 1px solid #1c3852; border-radius: 8px; font-size: 14px; background: #091524; color: var(--text-primary); }
.form input::placeholder, .form textarea::placeholder { color: #6b8aa7; }
.actions { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.muted { color: var(--text-muted); font-size: 14px; }
.footer { padding: 30px 0; border-top: 1px solid var(--card-border); background: linear-gradient(180deg, var(--bg-end), var(--bg-start)); color: var(--text-muted); }
@media (max-width: 900px) {
.grid-3 { grid-template-columns: 1fr; }
.grid-2 { grid-template-columns: 1fr; }
.logo-wall { grid-template-columns: repeat(3, 1fr); }
.hero h1 { font-size: 32px; }
}

BIN
doubao-asr-demo/.DS_Store vendored Normal file

Binary file not shown.

7
doubao-asr-demo/.env Normal file
View File

@ -0,0 +1,7 @@
DOU_BAO_API_KEY=ca6ac254-64ee-468c-9047-5f6404fa78f2
DOU_BAO_RESOURCE_ID=volc.bigasr.auc
DOU_BAO_SUBMIT_URL=https://openspeech.bytedance.com/api/v3/auc/bigmodel/submit
DOU_BAO_RESULT_URL=https://openspeech.bytedance.com/api/v3/auc/bigmodel/query
PORT=6174
SERVE_STATIC=true
STATIC_PORT=4173

View File

@ -0,0 +1,6 @@
# 豆包 ASR 代理配置示例
DOU_BAO_API_KEY=替换为豆包控制台生成的APIKey
DOU_BAO_RESOURCE_ID=volc.bigasr.auc
DOU_BAO_SUBMIT_URL=https://openspeech.bytedance.com/api/v3/auc/bigmodel/submit
DOU_BAO_RESULT_URL=https://openspeech.bytedance.com/api/v3/auc/bigmodel/get_result
PORT=5174

86
doubao-asr-demo/README.md Normal file
View File

@ -0,0 +1,86 @@
# 豆包语音转写演示
本项目提供一个简单的前端页面用于上传音频并调用豆包语音转写接口submit/get_result同时包含一个 Node.js 代理服务,避免在前端暴露 API Key 与跨域问题。
## 项目结构
```
doubao-asr-demo/
├── index.html # 前端页面入口
├── main.js # 前端逻辑
├── styles.css # 页面样式
├── server/
│ └── index.js # Node 代理服务Express
├── .env.example # 代理环境变量示例
├── package.json
└── package-lock.json
```
## 快速启动
1. 克隆或下载项目后进入目录
```bash
cd doubao-asr-demo
```
2. 安装依赖
```bash
npm install
```
3. 准备环境变量
复制 `.env.example``.env`,填入豆包平台申请的密钥:
```
cp .env.example .env
# 编辑 .env至少配置 DOU_BAO_API_KEY
```
主要变量说明:
- `DOU_BAO_API_KEY`:豆包开放平台生成的 API Key必填
- `DOU_BAO_RESOURCE_ID`:资源 ID默认 `volc.bigasr.auc`
- `DOU_BAO_SUBMIT_URL``DOU_BAO_RESULT_URL`:如无特殊需求保持默认
- `PORT`:代理服务监听端口,默认 5174
4. 启动代理服务
```bash
npm run dev
```
代理启动后默认监听 `http://localhost:5174`
5. 启动静态资源服务
使用任意方式托管静态页面(如 VS Code Live Server、`python -m http.server` 等),或将页面放入任意静态网站服务器。必须保证页面能访问到代理服务 `http://localhost:5174`
示例:
```bash
python3 -m http.server 4173
```
然后在浏览器访问 `http://localhost:4173/index.html`
## 使用方法
1. 在页面选择音频文件,填写必要参数。
2. 如果本地代理已启动且地址为默认值可将“API 基础地址”留空,前端会自动调用代理接口 `/api/asr/...`
3. 若需要直连豆包官方接口在“API 基础地址”输入官方地址,并确保浏览器环境允许该接口的 CORS通常不可行。此时必须在页面中填写 `X-Api-Key`,否则会提示错误。
4. 点击“提交识别任务”,页面会先提交任务,再自动轮询结果并展示转写文本,同时在“调试日志”中输出详细日志。
## 注意事项
- 前端直接调用官方接口会暴露密钥且受 CORS 限制,强烈建议通过本项目提供的代理转发。
- 代理只作为演示用途,生产环境请增加鉴权、限流、日志、安全审计等措施。
- 上传音频大小受限于前端与代理的请求体限制(默认 12 MB可根据实际需要调整。
- 如果豆包接口返回的字段结构与示例不同,请在 `main.js` 中调整 `extractTranscript` 解析逻辑。
## 常见问题
- **Failed to fetch**:通常因为前端直连被 CORS 拒绝或未启动代理,请使用代理方式或检查网络。
- **服务器未配置 DOU_BAO_API_KEY**:请确认 `.env` 已设置该变量,并在启动代理前加载。
- **轮询超时**:可根据实际需求增加 `maxAttempts``pollIntervalMs`,同时检查豆包接口是否正常返回。

248
doubao-asr-demo/index.html Normal file
View File

@ -0,0 +1,248 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="filename" content="audio-to-text-tool.html">
<title>录音文件转文字工具</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&family=Noto+Sans+SC:wght@400;500;700&display=swap" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<!-- 使用页面内样式,避免旧样式冲突 -->
<style>
/* 省略:保留你提供的全部样式,未改动 */
:root { --primary: #4361ee; --primary-light: #5a9cff; --primary-dark: #3a0ca3; --success: #41d6a4; --warning: #ffb020; --error: #ff4d4f; --bg-light: #f9fafc; --bg-dark: #101827; --text-light: #111827; --text-dark: #e2e8f0; --card-bg-light: #ffffff; --card-bg-dark: #1e293b; --border-light: #e2e8f0; --border-dark: #334155; --gray-100: #f1f5f9; --gray-200: #e2e8f0; --gray-300: #cbd5e1; --gray-700: #334155; --font-main: 'Poppins', 'Noto Sans SC', system-ui, sans-serif; --font-secondary: 'SF Pro', 'Helvetica Neue', sans-serif; --radius: 16px; --shadow: 0 10px 20px rgba(0, 0, 0, 0.08); --shadow-dark: 0 10px 20px rgba(0, 0, 0, 0.2); --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); }
* { margin:0; padding:0; box-sizing:border-box; }
body { background: linear-gradient(135deg, #f0f4ff 0%, #e6f0ff 100%); color: var(--text-light); font-family: var(--font-main); margin: 0; padding: 0; display: flex; justify-content: center; min-height: 100vh; transition: var(--transition); }
body.dark-mode { background: linear-gradient(135deg, #0c142a 0%, #101e3c 100%); color: var(--text-dark); }
::-webkit-scrollbar { width:8px; } ::-webkit-scrollbar-track { background: var(--gray-100); border-radius:4px; } body.dark-mode ::-webkit-scrollbar-track { background: var(--gray-700);} ::-webkit-scrollbar-thumb { background: var(--primary); border-radius:4px; }
.app-container { width:100%; max-width:1400px; margin:2rem; }
.navbar { display:flex; justify-content:space-between; align-items:center; margin-bottom:2.5rem; padding:0.5rem 1rem; background: var(--card-bg-light); border-radius: var(--radius); box-shadow: var(--shadow); transition: var(--transition); }
body.dark-mode .navbar { background: var(--card-bg-dark); box-shadow: var(--shadow-dark); }
.brand { display:flex; align-items:center; gap:16px; }
.logo-svg { height:44px; width:44px; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); border-radius:12px; display:flex; align-items:center; justify-content:center; }
.logo-svg svg { width:24px; height:24px; fill:white; }
.brand-info h1 { font-size:1.8rem; font-weight:700; margin-bottom:4px; color: var(--primary); letter-spacing:-0.5px; }
.brand-info p { font-size:0.9rem; color: var(--gray-700); }
body.dark-mode .brand-info p { color: var(--gray-300);}
.navbar-controls { display:flex; align-items:center; gap:1.5rem; }
.language-select { padding:0.8rem 1.4rem; background: var(--card-bg-light); border:1px solid var(--border-light); border-radius:12px; cursor:pointer; display:flex; align-items:center; gap:12px; transition: var(--transition); font-weight:500; }
body.dark-mode .language-select { background: var(--card-bg-dark); border-color: var(--border-dark);}
.language-select:hover { border-color: var(--primary);}
.theme-toggle { background: var(--card-bg-light); border:1px solid var(--border-light); height:50px; width:50px; border-radius:50%; display:flex; align-items:center; justify-content:center; cursor:pointer; transition: var(--transition);}
body.dark-mode .theme-toggle { background: var(--card-bg-dark); border-color: var(--border-dark);}
.theme-toggle:hover { background: var(--gray-100); transform: rotate(20deg);} body.dark-mode .theme-toggle:hover { background: rgba(255,255,255,0.1);}
.content-grid { display:grid; grid-template-columns: 1fr 1fr 1fr; gap:2rem; margin-bottom:2rem; }
@media (max-width:1200px){ .content-grid { grid-template-columns: 1fr 1fr; } } @media (max-width:768px){ .content-grid { grid-template-columns: 1fr; } }
.card { border-radius: var(--radius); overflow:hidden; box-shadow: var(--shadow); background: var(--card-bg-light); transition: var(--transition); position:relative; margin-bottom:2rem; }
body.dark-mode .card { background: var(--card-bg-dark); box-shadow: var(--shadow-dark);}
.card:hover { transform: translateY(-5px); box-shadow: 0 15px 30px rgba(0,0,0,0.15);} body.dark-mode .card:hover { box-shadow: 0 15px 30px rgba(0,0,0,0.3);}
.card-header { padding:1.8rem 1.8rem 1.2rem; display:flex; align-items:center; font-weight:600; gap:0.75rem; border-bottom:1px solid var(--border-light); font-size:1.2rem; color: var(--primary);} body.dark-mode .card-header { border-bottom:1px solid var(--border-dark);}
.card-body { padding:2rem; }
.upload-area { display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; padding:4rem 2rem; border:2px dashed var(--border-light); border-radius: var(--radius); cursor:pointer; transition: var(--transition); position:relative; background: rgba(67,97,238,0.03);} body.dark-mode .upload-area { border-color: var(--border-dark); background: rgba(33,66,164,0.05);} .upload-area:hover { border-color: var(--primary); background: rgba(67,97,238,0.08);} .upload-area.active { background: rgba(67,97,238,0.1); border-color: var(--primary); border-style: solid; }
.upload-icon { font-size:4.5rem; color: var(--primary); margin-bottom:1.5rem; display:flex; align-items:center; justify-content:center; }
.upload-text { font-size:1.4rem; margin-bottom:1.2rem; font-weight:500; color: var(--text-light);} body.dark-mode .upload-text { color: var(--text-dark);}
.upload-info { color: var(--gray-700); font-size:1rem; margin-bottom:1.5rem; max-width:90%; } body.dark-mode .upload-info { color: var(--gray-300);}
.file-input { opacity:0; position:absolute; top:0; left:0; width:100%; height:100%; cursor:pointer; z-index:2; }
.btn { padding:1.1rem 3rem; border-radius: var(--radius); border:none; cursor:pointer; font-weight:600; transition: var(--transition); display:inline-flex; align-items:center; justify-content:center; gap:12px; font-size:1.1rem; position:relative; overflow:hidden; z-index:1; }
.btn::after { content:''; position:absolute; width:100%; height:0; top:50%; left:50%; background: rgba(255,255,255,0.2); opacity:0; transform: translateX(-50%) translateY(-50%) rotate(0deg); transition: all .5s; z-index:-1; } .btn:hover::after { height:350%; opacity:1;} .btn:active::after { height:500%; opacity:0; }
.btn-primary { background: linear-gradient(90deg, var(--primary), var(--primary-light)); color:white; box-shadow: 0 8px 20px rgba(67,97,238,0.3);} .btn-primary:hover { background: linear-gradient(90deg, var(--primary-dark), var(--primary)); box-shadow: 0 12px 25px rgba(58,12,163,0.4);}
.btn-secondary { background: var(--gray-100); color: var(--text-light);} body.dark-mode .btn-secondary { background: var(--gray-700); color: var(--text-dark);}
.btn-success { background: var(--success); color:white; box-shadow: 0 8px 20px rgba(65,214,164,0.3);} .btn-success:hover { background:#2a9d7d; box-shadow: 0 12px 25px rgba(42,157,125,0.4);}
.status-grid { display:grid; grid-template-columns: 1fr 1fr; gap:2rem; margin-bottom:2rem; }
.progress-container { width:100%; display:flex; flex-direction:column; justify-content:center; }
.progress-header { display:flex; justify-content:space-between; margin-bottom:1.5rem; }
.progress-label { font-size:1.25rem; font-weight:500; color: var(--text-light);} body.dark-mode .progress-label { color: var(--text-dark);}
.progress-percent { font-weight:700; color: var(--primary); font-size:1.4rem; }
.progress-bar { height:16px; background-color: var(--gray-200); border-radius:8px; overflow:hidden; } body.dark-mode .progress-bar { background-color: var(--gray-700);}
.progress-fill { height:100%; background: linear-gradient(90deg, var(--primary), var(--primary-light)); border-radius:8px; width:0%; transition: width 0.4s ease; box-shadow: 2px 0 10px rgba(67,97,238,0.4);}
.progress-info { display:flex; justify-content:space-between; margin-top:1rem; font-size:1rem; color: var(--gray-700);} body.dark-mode .progress-info { color: var(--gray-300);}
.status-animation { display:flex; align-items:center; justify-content:center; height:160px;} .sound-wave { display:flex; align-items:center; height:130px; gap:12px;} .sound-bar { width:10px; background-color: var(--primary); border-radius:5px; animation: sound-wave 1.2s ease-in-out infinite; box-shadow: 0 0 10px rgba(67,97,238,0.3);} @keyframes sound-wave { 0%,100%{ transform: scaleY(0.7) translateY(10px); background-color: var(--primary-light);} 50%{ transform: scaleY(1.5) translateY(0); background-color: var(--primary);} } .sound-bar:nth-child(1){ height:30px; animation-delay:0s;} .sound-bar:nth-child(2){ height:50px; animation-delay:0.1s;} .sound-bar:nth-child(3){ height:70px; animation-delay:0.2s;} .sound-bar:nth-child(4){ height:100px; animation-delay:0.3s;} .sound-bar:nth-child(5){ height:70px; animation-delay:0.4s;} .sound-bar:nth-child(6){ height:50px; animation-delay:0.5s;} .sound-bar:nth-child(7){ height:30px; animation-delay:0.6s;}
.status-detail { text-align:center; margin-top:2rem;} .status-detail p { font-size:1.2rem; margin-bottom:0.5rem; line-height:1.7;} .highlight-text { color: var(--primary); font-weight:700; display:inline-block; }
.result-container { display:grid; grid-template-columns: 1fr 1fr; gap:2rem; } @media (max-width:1200px){ .result-container { grid-template-columns: 1fr; } }
.audio-player-section { display:flex; flex-direction:column; gap:2rem; }
.audio-cover { width:100%; height:280px; border-radius: var(--radius); background-color: var(--gray-200); background-image: url('https://images.unsplash.com/photo-1505740420928-5e560c06d30e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80'); background-size: cover; background-position:center; position:relative; overflow:hidden; box-shadow: inset 0 -60px 40px -20px rgba(0,0,0,0.7);}
.audio-info { position:absolute; bottom:0; left:0; right:0; padding:2rem; color:white; } .audio-info h3 { font-size:1.8rem; margin-bottom:0.7rem; font-weight:700; text-shadow: 0 2px 4px rgba(0,0,0,0.5);} .audio-info p { opacity:0.9; font-size:1.1rem; text-shadow: 0 1px 2px rgba(0,0,0,0.5);}
.audio-controls { background: var(--card-bg-light); border-radius: var(--radius); padding:2rem; display:flex; flex-direction:column; gap:1.5rem; box-shadow: var(--shadow);} body.dark-mode .audio-controls { background: var(--card-bg-dark); box-shadow: var(--shadow-dark);}
.control-bar { display:flex; align-items:center; gap:1.8rem; } .play-btn { width:60px; height:60px; border-radius:50%; background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color:white; display:flex; align-items:center; justify-content:center; border:none; cursor:pointer; transition: var(--transition); box-shadow: 0 6px 15px rgba(58,12,163,0.5);} .play-btn:hover { transform: scale(1.08); box-shadow: 0 8px 20px rgba(58,12,163,0.7);}
.progress-audio { flex:1; position:relative; } .progress-seek { width:100%; height:8px; background: var(--gray-200); border-radius:4px; cursor:pointer; position:relative;} body.dark-mode .progress-seek { background: var(--gray-700);} .progress-current { height:100%; background: linear-gradient(90deg, var(--primary), var(--primary-light)); border-radius:4px; position:absolute; top:0; left:0; width:0%; transition: width 0.2s ease;}
.time-indicators { display:flex; justify-content:space-between; margin-top:0.8rem; font-size:1rem; font-weight:500; color: var(--gray-700);} body.dark-mode .time-indicators { color: var(--gray-300);}
.secondary-controls { display:flex; justify-content:space-between; align-items:center;} .control-group { display:flex; align-items:center; gap:1.5rem;} .control-btn { background: rgba(67,97,238,0.1); border:none; width:42px; height:42px; border-radius:12px; display:flex; align-items:center; justify-content:center; cursor:pointer; color: var(--primary); transition: var(--transition);} body.dark-mode .control-btn { background: rgba(67,97,238,0.15);} .control-btn:hover { background: rgba(67,97,238,0.2); transform: translateY(-3px);} body.dark-mode .control-btn:hover { background: rgba(67,97,238,0.3);}
.dropdown { background: var(--card-bg-light); border:1px solid var(--border-light); border-radius:12px; padding:0.6rem 1.2rem; font-weight:500; font-size:1rem;} body.dark-mode .dropdown { background: var(--card-bg-dark); border:1px solid var(--border-dark);}
.transcript-area { display:flex; flex-direction:column; height:100%; gap:1.5rem;}
.transcript-content { flex:1; background: var(--card-bg-light); border-radius: var(--radius); padding:2.2rem; overflow-y:auto; box-shadow: var(--shadow);} body.dark-mode .transcript-content { background: var(--card-bg-dark); box-shadow: var(--shadow-dark);}
.transcript-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:1.8rem; padding-bottom:1.2rem; border-bottom:1px solid var(--border-light);} body.dark-mode .transcript-header { border-bottom-color: var(--border-dark);}
.speaker-tags { display:flex; gap:1rem; flex-wrap:wrap; }
.speaker-tag { background: var(--primary); color:white; padding:0.45rem 1.3rem; border-radius:24px; font-size:1rem; font-weight:600; box-shadow: 0 4px 8px rgba(0,0,0,0.1);}
.tag-1 { background: linear-gradient(90deg, #4361ee, #4895ef);} .tag-2 { background: linear-gradient(90deg, #41d6a4, #2e9d7d);} .tag-3 { background: linear-gradient(90deg, #f15bb5, #ae3f85);}
.tool-btn { background: rgba(67,97,238,0.1); border:none; padding:0.7rem 1.2rem; border-radius:8px; cursor:pointer; color: var(--primary); font-weight:500; transition: var(--transition);} .tool-btn:hover { background: rgba(67,97,238,0.2);}
.transcript-lines { display:flex; flex-direction:column; gap:1.5rem; }
.transcript-line { padding:1.5rem; border-radius:14px; transition: var(--transition); position:relative; cursor:pointer; }
body.dark-mode .transcript-line { background: rgba(255,255,255,0.03);} .transcript-line:not(.active):hover { background: rgba(67,97,238,0.05);} .transcript-line.active { background: rgba(67,97,238,0.1); border-left:5px solid var(--primary); box-shadow: 0 4px 12px rgba(67,97,238,0.1);}
.timestamp { font-size:0.9rem; font-weight:600; color: var(--primary); margin-bottom:0.5rem; display:block; background: rgba(67,97,238,0.1); padding:0.3rem 0.8rem; border-radius:20px; display:inline-block; transition: var(--transition);} body.dark-mode .timestamp { color: var(--primary-light);} .timestamp:hover { background: rgba(67,97,238,0.2);}
.speaker { font-weight:700; font-size:1.1rem; margin-right:0.5rem; display:inline-block; padding:0.3rem 1rem; border-radius:18px; color:white; }
.text-content { line-height:1.75; margin-top:0.8rem; font-size:1.05rem; }
.action-bar { display:flex; justify-content:flex-end; gap:1.5rem; padding:1.5rem 0 0; }
.action-btn { padding:1.1rem 2.2rem; border-radius: var(--radius); border:none; cursor:pointer; font-weight:600; transition: var(--transition); display:inline-flex; align-items:center; gap:10px; font-size:1.1rem; }
.action-success { background: var(--success); color:white; box-shadow: 0 8px 20px rgba(65,214,164,0.3);} .action-secondary { background: var(--gray-100); color: var(--text-light);} body.dark-mode .action-secondary { background: var(--gray-700); color: var(--text-dark);} .action-secondary:hover { background: var(--gray-200);} body.dark-mode .action-secondary:hover { background: var(--gray-600);}
.footer { text-align:center; padding:2rem; color: var(--gray-700); font-size:0.95rem; margin-top:2rem; border-top:1px solid var(--border-light);} body.dark-mode .footer { color: var(--gray-300); border-top-color: var(--border-dark);}
</style>
</head>
<body>
<div class="app-container">
<div class="navbar">
<div class="brand">
<div class="logo-svg">
<svg viewBox="0 0 24 24"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
</div>
<div class="brand-info">
<h1>AudioToText Pro</h1>
<p>智能语音识别与转换解决方案</p>
</div>
</div>
<div class="navbar-controls">
<div class="language-select">
<i class="fas fa-globe"></i>
<span>自动检测语言</span>
<i class="fas fa-chevron-down"></i>
</div>
<button class="theme-toggle" id="themeToggle"><i class="fas fa-moon"></i></button>
</div>
</div>
<div class="content-grid">
<div class="card">
<div class="card-header"><i class="fas fa-file-upload"></i><span>上传录音文件</span></div>
<div class="card-body">
<div class="upload-area" id="uploadArea">
<div class="upload-icon"><i class="fas fa-cloud-upload-alt"></i></div>
<p class="upload-text">拖拽录音文件到这里或点击上传</p>
<p class="upload-info">支持 MP3, WAV, FLAC, AAC, M4A 等格式最大500MB</p>
<button class="btn btn-primary" onclick="document.getElementById('fileInput').click()"><i class="fas fa-upload"></i> 选择文件</button>
<input type="file" class="file-input" id="fileInput" accept="audio/*">
</div>
</div>
</div>
<div class="card">
<div class="card-header"><i class="fas fa-arrow-up"></i><span>上传状态</span></div>
<div class="card-body">
<div class="progress-container">
<div class="progress-header"><span class="progress-label">文件上传进度</span><span class="progress-percent" id="uploadPercent">0%</span></div>
<div class="progress-bar"><div class="progress-fill" id="uploadFill"></div></div>
<div class="progress-info"><span id="uploadFileName">未选择文件</span><span id="uploadEta">准备就绪</span></div>
</div>
</div>
</div>
<div class="card" id="analysisCard">
<div class="card-header"><i class="fas fa-cogs"></i><span>转写分析</span></div>
<div class="card-body">
<div class="status-animation"><div class="sound-wave"><div class="sound-bar"></div><div class="sound-bar"></div><div class="sound-bar"></div><div class="sound-bar"></div><div class="sound-bar"></div><div class="sound-bar"></div><div class="sound-bar"></div></div></div>
<div class="status-detail">
<p>AI正在分析音频内容识别不同发言者</p>
<p>转写用时 <span class="highlight-text" id="analysisProgress">00:00</span></p>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-body">
<div class="result-container">
<div class="audio-player-section">
<div class="audio-cover"><div class="audio-info"><h3 id="audioTitle">录音文件</h3><p id="audioMeta"></p></div></div>
<div class="audio-controls">
<div class="control-bar">
<button class="play-btn" id="playBtn"><i class="fas fa-play"></i></button>
<div class="progress-audio">
<div class="progress-seek"><div class="progress-current" id="audioProgress"></div></div>
<div class="time-indicators"><span id="currentTime">0:00</span><span id="totalTime"></span></div>
</div>
</div>
<div class="secondary-controls">
<div class="control-group">
<button class="control-btn" id="stepBack"><i class="fas fa-step-backward"></i></button>
<button class="control-btn" id="stepForward"><i class="fas fa-step-forward"></i></button>
<button class="control-btn" id="redoBtn"><i class="fas fa-redo"></i></button>
</div>
<div class="control-group">
<button class="control-btn"><i class="fas fa-volume-up"></i></button>
<div class="dropdown"><select id="speedSelect"><option>1.0x</option><option>0.75x</option><option>1.25x</option><option>1.5x</option><option>2.0x</option></select></div>
</div>
</div>
</div>
</div>
<div class="transcript-area">
<div class="transcript-header">
<div class="speaker-tags" id="speakerTags"></div>
<button class="tool-btn" id="editToggle"><i class="fas fa-edit"></i> 编辑</button>
<button class="tool-btn" id="saveSpkBtn" style="display:none"><i class="fas fa-save"></i> 保存</button>
</div>
<div class="transcript-content">
<div class="transcript-lines" id="transcriptLines"></div>
</div>
</div>
</div>
<div class="action-bar">
<button class="action-secondary action-btn" id="convertBtn"><i class="fas fa-redo"></i> 重新转换</button>
<button class="action-secondary action-btn" id="copyAllBtn"><i class="fas fa-copy"></i> 复制全文</button>
<button class="action-success action-btn" id="exportBtn"><i class="fas fa-download"></i> 导出文件</button>
</div>
</div>
</div>
<!-- 调试日志卡片(置底) -->
<div class="card">
<div class="card-header"><i class="fas fa-terminal"></i><span>调试日志</span></div>
<div class="card-body">
<div class="action-bar" style="justify-content: flex-end; padding: 0; margin-bottom: 1rem;">
<button class="tool-btn" id="copyDebugBtn"><i class="fas fa-copy"></i> 复制日志全文</button>
</div>
<div class="transcript-content" style="max-height: 40vh;">
<pre id="debugLog">等待提交…</pre>
</div>
</div>
</div>
<div class="footer"><p>AudioToText Pro &copy; 2025 | 高精度语音识别解决方案</p></div>
</div>
<!-- 主题与上传交互保留;识别、渲染由 main.js 接管 -->
<script>
const themeToggle = document.getElementById('themeToggle');
const body = document.body;
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') { body.classList.add('dark-mode'); themeToggle.innerHTML = '<i class="fas fa-sun"></i>'; }
themeToggle.addEventListener('click', () => {
body.classList.toggle('dark-mode');
if (body.classList.contains('dark-mode')) { themeToggle.innerHTML = '<i class="fas fa-sun"></i>'; localStorage.setItem('theme', 'dark'); }
else { themeToggle.innerHTML = '<i class="fas fa-moon"></i>'; localStorage.setItem('theme', 'light'); }
});
const uploadArea = document.getElementById('uploadArea');
const fileInput = document.getElementById('fileInput');
uploadArea.addEventListener('dragover', (e) => { e.preventDefault(); uploadArea.classList.add('active'); });
uploadArea.addEventListener('dragleave', () => { uploadArea.classList.remove('active'); });
function startAnalysisTimer(){ const el=document.getElementById('analysisProgress'); const started=Date.now(); if (!startAnalysisTimer._timer){ startAnalysisTimer._timer=setInterval(()=>{ const ms=Date.now()-started; const mm=Math.floor(ms/60000).toString().padStart(2,'0'); const ss=Math.floor((ms%60000)/1000).toString().padStart(2,'0'); el.textContent=`${mm}:${ss}`; },1000);} }
uploadArea.addEventListener('drop', (e) => { e.preventDefault(); uploadArea.classList.remove('active'); if (e.dataTransfer.files.length) { fileInput.files = e.dataTransfer.files; const f=e.dataTransfer.files[0]; document.getElementById('uploadFileName').textContent=f.name; document.getElementById('uploadPercent').textContent='100%'; document.getElementById('uploadFill').style.width='100%'; startAnalysisTimer(); } });
fileInput.addEventListener('change', () => { if (fileInput.files.length){ const f=fileInput.files[0]; document.getElementById('uploadFileName').textContent=f.name; document.getElementById('uploadPercent').textContent='100%'; document.getElementById('uploadFill').style.width='100%'; startAnalysisTimer(); } });
const copyDebugBtn = document.getElementById('copyDebugBtn');
copyDebugBtn?.addEventListener('click', async () => { try { const txt = document.getElementById('debugLog')?.textContent || ''; await navigator.clipboard.writeText(txt); } catch(e){} });
const playBtn = document.getElementById('playBtn');
playBtn.addEventListener('click', () => { const icon=playBtn.querySelector('i'); icon.classList.toggle('fa-play'); icon.classList.toggle('fa-pause'); });
</script>
<script>
(function(){
function wlog(msg){
try{var el=document.getElementById('debugLog'); if(el){ var ts=new Date().toISOString(); el.textContent = (el.textContent&&el.textContent!=='等待提交…'? (el.textContent+'\n'): '') + '['+ts+'] '+msg; }}catch(e){}
}
window.addEventListener('error', function(e){ wlog('全局错误: '+ (e.message||e.error||e.filename||'unknown')); });
window.addEventListener('unhandledrejection', function(e){ wlog('未捕获的Promise拒绝: '+ (e.reason&&e.reason.message?e.reason.message:JSON.stringify(e.reason||{}))); });
wlog('调试桥已安装');
})();
</script>
<script src="main.js?v=3"></script>
</body>
</html>

2401
doubao-asr-demo/logs/asr.log Normal file

File diff suppressed because one or more lines are too long

973
doubao-asr-demo/main.js Normal file
View File

@ -0,0 +1,973 @@
const formElement = null; // 旧表单已移除使用新UI按钮触发
const submitButton = document.getElementById("submitButton");
let debugLogElement = document.getElementById("debugLog") || null;
const transcriptElement = document.getElementById("transcriptOutput") || null;
const downloadTxtBtn = document.getElementById("downloadTxtBtn");
const downloadSrtBtn = document.getElementById("downloadSrtBtn");
const copyBtn = document.getElementById("copyBtn");
const viewModeSelect = document.getElementById("viewMode");
const exportRangeTxtBtn = document.getElementById("exportRangeTxt");
const exportRangeSrtBtn = document.getElementById("exportRangeSrt");
const exportCsvBtn = document.getElementById("exportCsv");
const rangeStartInput = document.getElementById("rangeStart");
const rangeEndInput = document.getElementById("rangeEnd");
const exportToolbar = document.getElementById("exportToolbar");
let lastResultJson = null;
const editedMap = new Map(); // key: `${start}-${end}` -> edited text
// 说话人显示名与颜色映射
const speakerNameMap = new Map(); // key: speakerId -> display name (可编辑)
const speakerColorMap = new Map(); // key: speakerId -> 1..3 映射到 tag-1..tag-3
let editMode = false; // 是否开启“编辑说话人名称”
// 前端脚本加载标记,便于确认 JS 是否生效
appendLog('前端脚本已加载');
window.addEventListener('DOMContentLoaded', () => { debugLogElement = document.getElementById('debugLog'); appendLog('DOM 已就绪'); fetch('/health').then(r=>r.json()).then(j=>appendLog('健康检查:'+JSON.stringify(j))).catch(e=>appendLog('健康检查失败:'+e.message)); });
const proxySubmitEndpoint = "/api/asr/submit";
const proxyResultEndpoint = "/api/asr/result";
const pollIntervalMs = 2000;
const maxAttempts = 60;
const statusSuccessSet = new Set(["SUCCEEDED", "SUCCESS", "FINISHED"]);
const statusFailureSet = new Set(["FAILED", "FAIL", "ERROR"]);
function appendLog(message) {
const el = debugLogElement || document.getElementById("debugLog");
if (!el) return;
const timestamp = new Date().toISOString();
const nextLine = `[${timestamp}] ${message}`;
if (el.textContent === "等待提交…") {
el.textContent = nextLine;
} else {
el.textContent = `${el.textContent}\n${nextLine}`;
}
}
function resetOutputs() {
if (transcriptElement) transcriptElement.value = "";
if (debugLogElement) debugLogElement.textContent = "等待提交…";
const lines = document.getElementById('transcriptLines');
if (lines) lines.innerHTML = '';
const tags = document.getElementById('speakerTags');
if (tags) tags.innerHTML = '';
}
function stripDataUriPrefix(base64String) {
return base64String.replace(/^data:.*;base64,/, "");
}
function detectAudioFormat(nameOrUrl) {
if (!nameOrUrl || typeof nameOrUrl !== "string") return "wav";
let s = nameOrUrl.trim();
try {
// 若是 URL取 pathname 再去掉查询/锚点
const u = new URL(s);
s = u.pathname;
} catch (_) {
// 非 URL继续用原字符串
}
// 去掉查询/锚点残留
s = s.split("?")[0].split("#")[0];
const lastSlash = s.lastIndexOf("/");
if (lastSlash !== -1) s = s.slice(lastSlash + 1);
const lastDot = s.lastIndexOf(".");
if (lastDot === -1) return "wav";
const ext = s.slice(lastDot + 1).toLowerCase();
// 归一化若干别名
if (["m4a", "mp4a", "mp4"].includes(ext)) return "m4a";
if (ext === "oga") return "ogg";
return ext;
}
function readFileAsBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = () => reject(new Error("读取文件失败"));
reader.readAsDataURL(file);
});
}
function createHeaders({ useProxy, apiKey, resourceId, requestId }) {
const headers = new Headers();
headers.set("Content-Type", "application/json");
if (useProxy) {
return headers;
}
if (!apiKey) {
throw new Error("当直连豆包接口时必须填写 API Key");
}
headers.set("x-api-key", apiKey);
if (resourceId) {
headers.set("X-Api-Resource-Id", resourceId);
}
headers.set("X-Api-Request-Id", requestId);
headers.set("X-Api-Sequence", "-1");
return headers;
}
function buildSubmitPayload({
base64Data,
format,
sampleRate,
bits,
channels,
uid,
modelName,
options
}) {
return {
user: {
uid
},
audio: {
data: base64Data,
format,
codec: ["mp3", "wav", "pcm"].includes(format) ? "raw" : format,
rate: sampleRate,
bits,
channel: channels
},
request: {
model_name: modelName,
enable_itn: options.enableItn,
enable_punc: options.enablePunc,
enable_ddc: options.enableDdc,
enable_speaker_info: options.enableSpeaker,
enable_channel_split: options.enableChannelSplit,
show_utterances: options.showUtterances,
vad_segment: options.vadSegment,
sensitive_words_filter: options.sensitiveWords
}
};
}
function extractJobKey(result) {
const candidates = [
result?.result?.job_key,
result?.result?.task_id,
result?.result?.taskId,
result?.data?.job_key,
result?.data?.taskId,
result?.data?.task_id,
result?.job_key,
result?.task_id,
result?.taskId,
result?.RequestId,
result?.request_id
];
return candidates.find((value) => typeof value === "string" && value.length > 0) ?? null;
}
function deriveStatus(result) {
const candidates = [
result?.result?.status,
result?.result?.task_status,
result?.data?.status,
result?.data?.task_status,
result?.status
];
return candidates.find((value) => typeof value === "string" && value.length > 0) ?? null;
}
function flattenSegmentsText(segments) {
if (!Array.isArray(segments) || segments.length === 0) {
return null;
}
const texts = segments
.map((segment) => {
if (typeof segment?.text === "string" && segment.text.trim().length > 0) {
return segment.text.trim();
}
if (typeof segment?.transcript === "string" && segment.transcript.trim().length > 0) {
return segment.transcript.trim();
}
return null;
})
.filter((text) => typeof text === "string" && text.length > 0);
if (texts.length === 0) {
return null;
}
return texts.join("\n");
}
function extractTranscript(result) {
const segmentsTranscript =
flattenSegmentsText(result?.data?.result?.segments) ?? flattenSegmentsText(result?.result?.segments);
if (segmentsTranscript) {
return segmentsTranscript;
}
const candidates = [
result?.data?.result?.text,
result?.result?.text,
result?.result?.output?.choices?.[0]?.text,
result?.result?.output?.transcript,
result?.result?.transcript,
result?.data?.output?.choices?.[0]?.text,
result?.data?.transcript
];
return candidates.find((value) => typeof value === "string" && value.trim().length > 0) ?? null;
}
function msToTimestamp(ms) {
if (typeof ms !== "number" || Number.isNaN(ms)) return null;
const sign = ms < 0 ? "-" : "";
const t = Math.abs(ms);
const hours = Math.floor(t / 3600000);
const minutes = Math.floor((t % 3600000) / 60000);
const seconds = Math.floor((t % 60000) / 1000);
const millis = Math.floor(t % 1000);
const hh = hours.toString().padStart(2, "0");
const mm = minutes.toString().padStart(2, "0");
const ss = seconds.toString().padStart(2, "0");
const mmm = millis.toString().padStart(3, "0");
return `${sign}${hh}:${mm}:${ss}.${mmm}`;
}
function anyToMs(value) {
if (typeof value === "number") return value;
if (typeof value === "string") {
// 支持 "1.23" 秒或 "00:00:01.230"
if (/^\d+(\.\d+)?$/.test(value)) {
return Number(value) * 1000;
}
const m = value.match(/^(\d{2}):(\d{2}):(\d{2})\.(\d{1,3})$/);
if (m) {
const h = Number(m[1]);
const min = Number(m[2]);
const s = Number(m[3]);
const ms = Number(m[4].padEnd(3, "0"));
return ((h * 60 + min) * 60 + s) * 1000 + ms;
}
}
return null;
}
function extractSegments(obj) {
const segs = obj?.data?.result?.segments || obj?.result?.segments || obj?.segments || null;
if (Array.isArray(segs) && segs.length > 0) return segs;
// 兼容返回的 utterances 字段,转换为统一的段落结构
const utts = obj?.data?.result?.utterances || obj?.result?.utterances || obj?.utterances || null;
if (Array.isArray(utts) && utts.length > 0) {
return utts.map(u => ({
start_ms: u.start_ms ?? u.start_time ?? u.start,
end_ms: u.end_ms ?? u.end_time ?? u.end,
text: u.text,
channel: u.channel ?? u.channel_index ?? u.ch ?? u.additions?.channel_id,
speaker: u.speaker ?? u.spk ?? u.speaker_id ?? u.additions?.speaker
}));
}
return null;
}
function formatSegmentsDetailed(obj) {
const segments = extractSegments(obj);
if (!Array.isArray(segments) || segments.length === 0) return null;
const lines = [];
for (const seg of segments) {
const start = anyToMs(seg.start_ms ?? seg.start_time ?? seg.start ?? seg.begin_ms ?? seg.begin_time);
const end = anyToMs(seg.end_ms ?? seg.end_time ?? seg.end ?? seg.finish_ms ?? seg.finish_time);
const startTs = start != null ? msToTimestamp(start) : null;
const endTs = end != null ? msToTimestamp(end) : null;
const ch = seg.channel ?? seg.channel_index ?? seg.ch ?? null;
const spk = seg.speaker ?? seg.spk ?? seg.speaker_id ?? null;
const text = (typeof seg.text === "string" && seg.text.trim()) || (typeof seg.transcript === "string" && seg.transcript.trim()) || "";
const attrs = [];
if (ch != null) attrs.push(`ch=${ch}`);
if (spk != null) attrs.push(`spk=${spk}`);
const range = startTs && endTs ? `[${startTs}-${endTs}]` : (startTs ? `[${startTs}-?]` : (endTs ? `[?-${endTs}]` : ""));
const header = [range, attrs.length ? `(${attrs.join(", ")})` : ""].filter(Boolean).join(" ");
lines.push(header ? `${header} ${text}` : text);
}
return lines.join("\n");
}
function sleep(durationMs) {
return new Promise((resolve) => setTimeout(resolve, durationMs));
}
function buildSegmentsFromEdited(obj) {
const segs = extractSegments(obj) || [];
return segs.map(s => {
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0;
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0;
const key = `${start}-${end}`;
const text = editedMap.get(key) ?? s.text ?? s.transcript ?? "";
return { ...s, start_ms: start, end_ms: end, text };
});
}
function buildSrtFromSegments(obj) {
const segs = extractSegments(obj);
if (!Array.isArray(segs) || segs.length === 0) return null;
const blocks = [];
let idx = 1;
for (const s of segs) {
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start);
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end);
const startTs = msToTimestamp(start)?.replace(".", ",") ?? "00:00:00,000";
const endTs = msToTimestamp(end)?.replace(".", ",") ?? "00:00:00,000";
const spkId = s.speaker ?? s.spk ?? s.speaker_id;
const spkName = spkId != null ? (speakerNameMap.get(spkId) || `说话人 ${spkId}`) : "";
const text = (typeof s.text === "string" && s.text.trim()) || (typeof s.transcript === "string" && s.transcript.trim()) || "";
const prefix = spkName ? `[${spkName}] ` : "";
blocks.push(`${idx}\n${startTs} --> ${endTs}\n${prefix}${text}\n`);
idx += 1;
}
return blocks.join("\n");
}
function groupBySpeakerAndChannel(segs) {
const map = new Map(); // key: channel -> Map(speaker -> [segments])
for (const s of segs) {
const ch = s.channel ?? s.channel_index ?? s.ch ?? s.additions?.channel_id ?? "unknown";
const spk = s.speaker ?? s.spk ?? s.speaker_id ?? s.additions?.speaker ?? "unknown";
if (!map.has(ch)) map.set(ch, new Map());
const inner = map.get(ch);
if (!inner.has(spk)) inner.set(spk, []);
inner.get(spk).push(s);
}
return map;
}
function buildTimeline(durationMs, rulerEl, onJump) {
if (!rulerEl) return;
rulerEl.innerHTML = "";
if (!durationMs || durationMs <= 0) return;
const step = Math.max(10000, Math.floor(durationMs / 10)); // 10s 或更大
// Tooltip element
const tooltip = document.createElement("div");
tooltip.className = "tooltip";
tooltip.style.left = "0%";
rulerEl.appendChild(tooltip);
const updateTooltip = (x) => {
const width = rulerEl.clientWidth || 1;
const percent = Math.max(0, Math.min(1, x / width));
const t = Math.round(durationMs * percent);
tooltip.style.left = `${percent * 100}%`;
let label = msToTimestamp(t)?.slice(0, 12) || "";
const segs = Array.isArray(buildTimeline._segs) ? buildTimeline._segs : [];
const near = segs.find(s => {
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0;
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0;
return t >= start && t <= end;
});
if (near) {
const ch = near.channel ?? near.channel_index ?? near.ch;
const spk = near.speaker ?? near.spk ?? near.speaker_id;
const previewRaw = (near.text || near.transcript || "").replace(/\n/g, " ");
const preview = previewRaw.length > 36 ? (previewRaw.slice(0, 36) + "…") : previewRaw;
label = `${msToTimestamp(t)?.slice(0, 12)} • ch=${ch ?? "-"} spk=${spk ?? "-"}${preview}`;
}
tooltip.textContent = label;
};
rulerEl.addEventListener("mousemove", (e) => {
const x = e.offsetX ?? (e.clientX - rulerEl.getBoundingClientRect().left);
updateTooltip(x);
});
rulerEl.addEventListener("mouseenter", (e) => {
const x = e.offsetX ?? (e.clientX - rulerEl.getBoundingClientRect().left);
updateTooltip(x);
});
rulerEl.addEventListener("click", (e) => {
const x = e.offsetX ?? (e.clientX - rulerEl.getBoundingClientRect().left);
const percent = Math.max(0, Math.min(1, x / (rulerEl.clientWidth || 1)));
const t = Math.round(durationMs * percent);
onJump?.(t);
});
for (let t = 0; t <= durationMs; t += step) {
const p = (t / durationMs) * 100;
const tick = document.createElement("div");
tick.className = "tick";
tick.style.left = `${p}%`;
const label = document.createElement("div");
label.className = "label";
label.style.left = `${p}%`;
label.textContent = msToTimestamp(t)?.slice(0, 8) || "";
label.style.cursor = "pointer";
label.addEventListener("click", () => onJump?.(t));
rulerEl.appendChild(tick);
rulerEl.appendChild(label);
}
}
function highlightKeywords(text, keywords) {
if (!keywords || keywords.length === 0) return text;
let safe = text;
for (const kw of keywords) {
if (!kw) continue;
const re = new RegExp(`(${kw.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, "gi");
safe = safe.replace(re, '<span class="highlight">$1</span>');
}
return safe;
}
function renderStructuredView(json) { // 旧结构化保留但不使用
const segs = extractSegments(json) || [];
const container = document.getElementById("channelsContainer");
const ruler = document.getElementById("timelineRuler");
if (!container || !ruler) { appendLog('结构化容器缺失,跳过渲染'); return; }
const duration = anyToMs(json?.data?.additions?.duration || json?.result?.additions?.duration) || json?.audio_info?.duration || 0;
container.innerHTML = "";
buildTimeline._segs = segs;
buildTimeline(duration, ruler, (jumpMs) => {
// 时间轴点击 → 高亮对应时间附近的分段
const near = segs.filter(s => {
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0;
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0;
return jumpMs >= start && jumpMs <= end;
});
document.querySelectorAll('.segment-item.active').forEach(el => el.classList.remove('active'));
near.forEach(s => {
const selector = `.segment-item[data-start="${anyToMs(s.start_ms ?? s.start_time ?? s.start)}"][data-end="${anyToMs(s.end_ms ?? s.end_time ?? s.end)}"]`;
const el = container.querySelector(selector);
if (el) {
el.classList.add('active');
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
});
});
const channelMap = groupBySpeakerAndChannel(segs);
const keywordsInput = document.getElementById("sensitiveWords").value.trim();
const keywords = keywordsInput ? keywordsInput.split(/[,\s]+/).filter(Boolean) : [];
for (const [ch, speakerMap] of channelMap.entries()) {
const column = document.createElement("div");
column.className = "channel-column";
const header = document.createElement("div");
header.className = "channel-header";
header.innerHTML = `<span>声道 ch=${ch}</span><span>分组:说话人</span>`;
column.appendChild(header);
for (const [spk, items] of speakerMap.entries()) {
const group = document.createElement("div");
group.className = "speaker-group";
const title = document.createElement("div");
title.className = "speaker-title";
const avatar = document.createElement("span");
avatar.className = "speaker-avatar";
const colorIdx = (Number(spk) || 0) % 6 || 1;
avatar.style.background = getComputedStyle(document.documentElement).getPropertyValue(`--speaker-${colorIdx}`).trim() || "var(--accent)";
// 徽标文字:若为字符串取首字母/首个汉字,若为数字直接显示
let badgeText = "";
if (typeof spk === "string") {
const m = spk.match(/[A-Za-z\u4e00-\u9fa5]/);
badgeText = (m ? m[0] : spk[0] || "?").toUpperCase();
} else {
badgeText = String(spk ?? "?");
}
avatar.textContent = badgeText;
const label = document.createElement("span");
label.textContent = `说话人 ${spk}`;
title.appendChild(avatar);
title.appendChild(label);
group.appendChild(title);
for (const s of items) {
const item = document.createElement("div");
item.className = "segment-item";
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start);
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end);
item.dataset.start = String(start ?? 0);
item.dataset.end = String(end ?? 0);
const meta = document.createElement("div");
meta.className = "segment-meta";
meta.textContent = `[${msToTimestamp(start)} - ${msToTimestamp(end)}]`;
const text = document.createElement("div");
text.contentEditable = "true";
text.className = "editable";
const raw = (typeof s.text === "string" && s.text.trim()) || (typeof s.transcript === "string" && s.transcript.trim()) || "";
const key = `${start}-${end}`;
if (!editedMap.has(key)) editedMap.set(key, raw);
text.innerHTML = highlightKeywords(editedMap.get(key), keywords);
text.addEventListener("input", () => {
editedMap.set(key, text.textContent || "");
});
item.appendChild(meta);
item.appendChild(text);
group.appendChild(item);
}
column.appendChild(group);
}
container.appendChild(column);
}
}
function renderByViewMode() { /* 旧视图切换不再使用 */ }
// 旧视图切换移除
function withinRange(s, fromMs, toMs) {
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0;
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0;
return (fromMs == null || end >= fromMs) && (toMs == null || start <= toMs);
}
function parseTimeInput(v) {
if (!v) return null;
const s = v.trim();
if (/^\d+$/.test(s)) return Number(s);
const m = s.match(/^(\d{1,2}):(\d{2})(?::(\d{2}))?$/);
if (m) {
const h = m[3] ? Number(m[1]) : 0;
const min = m[3] ? Number(m[2]) : Number(m[1]);
const sec = m[3] ? Number(m[3]) : Number(m[2]);
return ((h * 60 + min) * 60 + sec) * 1000;
}
return null;
}
exportRangeTxtBtn?.addEventListener("click", () => {
if (!lastResultJson) return;
const fromMs = parseTimeInput(rangeStartInput?.value);
const toMs = parseTimeInput(rangeEndInput?.value);
const segs = buildSegmentsFromEdited(lastResultJson).filter(s => withinRange(s, fromMs, toMs));
const text = segs.map(s => s.text || s.transcript || "").join("\n");
triggerDownload(text, "transcript_range.txt");
});
exportRangeSrtBtn?.addEventListener("click", () => {
if (!lastResultJson) return;
const fromMs = parseTimeInput(rangeStartInput?.value);
const toMs = parseTimeInput(rangeEndInput?.value);
const segs = buildSegmentsFromEdited(lastResultJson).filter(s => withinRange(s, fromMs, toMs));
const srt = (function buildPartialSrt(items){
if (!items.length) return "";
let idx = 1; const out = [];
for (const s of items) {
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0;
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0;
const startTs = msToTimestamp(start)?.replace(".", ",") ?? "00:00:00,000";
const endTs = msToTimestamp(end)?.replace(".", ",") ?? "00:00:00,000";
out.push(`${idx}\n${startTs} --> ${endTs}\n${s.text || s.transcript || ""}\n`);
idx += 1;
}
return out.join("\n");
})(segs);
triggerDownload(srt, "transcript_range.srt");
});
exportCsvBtn?.addEventListener("click", () => {
if (!lastResultJson) return;
const segs = buildSegmentsFromEdited(lastResultJson);
const header = ["start_ms","end_ms","channel","speaker","text"];
const rows = segs.map(s => [
anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0,
anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0,
s.channel ?? "",
s.speaker ?? "",
(s.text || s.transcript || "").replace(/"/g,'""')
]);
const csv = [header.join(","), ...rows.map(r => r.map(c => /[",\n]/.test(String(c)) ? `"${String(c)}"` : String(c)).join(","))].join("\n");
triggerDownload(csv, "transcript.csv");
});
const exportBtn = document.getElementById('exportBtn');
const copyAllBtn = document.getElementById('copyAllBtn');
copyAllBtn?.addEventListener("click", async () => {
try {
const segs = buildSegmentsFromEdited(lastResultJson || {});
const text = segs.map(s => s.text || s.transcript || "").join("\n");
await navigator.clipboard.writeText(text);
} catch (e) {}
});
function triggerDownload(content, filename) {
const blob = new Blob([content], { type: "text/plain;charset=utf-8" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
a.remove();
URL.revokeObjectURL(url);
}
downloadSrtBtn?.addEventListener("click", () => {
if (!lastResultJson) { return; }
const srt = buildSrtFromSegments({ ...lastResultJson, segments: buildSegmentsFromEdited(lastResultJson) });
const text = srt || (lastResultJson?.transcript || extractTranscript(lastResultJson) || "");
triggerDownload(text, srt ? "transcript.srt" : "transcript.txt");
});
// 统一走导出按钮事件
exportBtn?.addEventListener('click', () => {
if (!lastResultJson) { appendLog('暂无结果可下载'); return; }
// 导出为“带时间+说话人”的可读TXT
const segs = buildSegmentsFromEdited(lastResultJson);
const lines = segs.map(s => {
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0;
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0;
const time = `[${msToTimestamp(start)} - ${msToTimestamp(end)}]`;
const spkId = s.speaker ?? s.spk ?? s.speaker_id;
const spk = spkId != null ? (speakerNameMap.get(spkId) || `说话人 ${spkId}`) : '';
const name = spk ? `${spk}: ` : '';
const text = (s.text || s.transcript || '').trim();
return `${time} ${name}${text}`;
});
const content = lines.join('\n');
triggerDownload(content, 'transcript.txt');
});
function renderInNewUI(json){
try{
const segs = extractSegments(json) || [];
const tagsEl = document.getElementById('speakerTags');
const linesEl = document.getElementById('transcriptLines');
const editToggle = document.getElementById('editToggle');
const saveSpkBtn = document.getElementById('saveSpkBtn');
if (tagsEl) tagsEl.innerHTML = '';
if (linesEl) linesEl.innerHTML = '';
// 收集说话人,建立稳定颜色映射(跨次渲染保持)
const speakers = [];
const spkSet = new Set();
for (const s of segs){
const spk = s.speaker ?? s.spk ?? s.speaker_id ?? null;
if (spk == null) continue;
if (!spkSet.has(spk)) { spkSet.add(spk); speakers.push(spk); }
if (!speakerColorMap.has(spk)) {
const used = new Set([...speakerColorMap.values()]);
const pool = [1,2,3,1,2,3];
const pick = pool.find(i => !used.has(i)) || ((speakerColorMap.size % 3) + 1);
speakerColorMap.set(spk, pick);
}
if (!speakerNameMap.has(spk)) {
speakerNameMap.set(spk, `说话人 ${spk}`);
}
}
// 渲染顶部可编辑标签
if (tagsEl){
speakers.forEach(spk => {
const colorIdx = speakerColorMap.get(spk) || 1;
const tag = document.createElement('span');
tag.className = `speaker-tag tag-${colorIdx}`;
tag.contentEditable = editMode ? 'true' : 'false';
tag.dataset.spk = String(spk);
tag.textContent = speakerNameMap.get(spk) || `说话人 ${spk}`;
tag.addEventListener('input', () => {
speakerNameMap.set(spk, tag.textContent || `说话人 ${spk}`);
// 同步更新下方所有同 speaker 的徽标文字
linesEl?.querySelectorAll(`[data-spk="${CSS.escape(String(spk))}"]`).forEach(el => {
el.textContent = speakerNameMap.get(spk);
});
});
tagsEl.appendChild(tag);
});
}
// 渲染正文每行
for (const s of segs){
if (!linesEl) break;
const spk = s.speaker ?? s.spk ?? s.speaker_id ?? null;
const item = document.createElement('div');
item.className = 'transcript-line';
const ts = document.createElement('span');
ts.className = 'timestamp';
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start);
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end);
ts.textContent = `[${msToTimestamp(start) || '00:00:00.000'} - ${msToTimestamp(end) || '00:00:00.000'}]`;
const sp = document.createElement('span');
const colorIdx = speakerColorMap.get(spk) || 1;
sp.className = `speaker tag-${colorIdx}`;
sp.dataset.spk = spk != null ? String(spk) : '';
if (spk != null) sp.textContent = speakerNameMap.get(spk) || `说话人 ${spk}`;
const text = document.createElement('div');
text.className = 'text-content';
text.textContent = (s.text || s.transcript || '').trim();
item.appendChild(ts);
if (spk != null) item.appendChild(sp);
item.appendChild(text);
linesEl.appendChild(item);
}
// 绑定编辑开关
if (editToggle){
editToggle.onclick = () => {
editMode = !editMode;
if (saveSpkBtn) saveSpkBtn.style.display = editMode ? 'inline-flex' : 'none';
tagsEl?.querySelectorAll('.speaker-tag').forEach(el => { el.contentEditable = editMode ? 'true' : 'false'; });
};
}
if (saveSpkBtn){
saveSpkBtn.onclick = () => {
tagsEl?.querySelectorAll('.speaker-tag').forEach(el => {
const spk = el.dataset.spk;
speakerNameMap.set(spk, el.textContent || `说话人 ${spk}`);
});
// 关闭编辑并同步正文徽标
editMode = false;
saveSpkBtn.style.display = 'none';
tagsEl?.querySelectorAll('.speaker-tag').forEach(el => { el.contentEditable = 'false'; });
linesEl?.querySelectorAll('.speaker').forEach(el => {
const spk = el.dataset.spk;
el.textContent = speakerNameMap.get(spk) || `说话人 ${spk}`;
});
};
}
}catch(e){ appendLog('渲染失败:' + (e?.message || String(e))); }
}
async function pollJobResult({ url, headers, body, useProxy }) {
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
appendLog(`${attempt} 次查询任务状态…`);
if (!useProxy && headers.has("X-Api-Request-Id")) {
headers.set("X-Api-Request-Id", (self.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`));
}
const response = await fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body)
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`查询失败HTTP ${response.status}${errorBody}`);
}
const json = await response.json().catch(() => {
throw new Error("解析查询结果时发生错误");
});
try {
const segs = extractSegments(json) || [];
const txt = extractTranscript(json) || '';
appendLog(`查询结果摘要segments=${segs.length}, transcriptLen=${txt.length}`);
} catch(_) { appendLog('查询结果已更新'); }
// 优先等待结构化分段segments/utterances仅文本不提前返回避免“只有一大段文本”的情况
const segs = extractSegments(json);
const hasSeg = Array.isArray(segs) && segs.length > 0;
const immediateTranscript = json?.transcript || extractTranscript(json);
if (hasSeg) {
return { ...json, transcript: immediateTranscript || null };
}
const status = deriveStatus(json);
if (!status) {
appendLog("未返回任务状态,继续轮询…");
} else if (statusSuccessSet.has(status.toUpperCase())) {
return json;
} else if (statusFailureSet.has(status.toUpperCase())) {
throw new Error(`任务失败,状态:${status}`);
}
await sleep(pollIntervalMs);
}
throw new Error("轮询超时,请稍后重试");
}
function readOptions() {
// 新UI默认全部开启且不展示敏感词过滤
return {
enableItn: true,
enablePunc: true,
enableDdc: true,
enableSpeaker: true,
enableChannelSplit: true,
showUtterances: true,
vadSegment: true,
sensitiveWords: "",
// 按你的需求默认不做声道拆分,避免同一句在左右声道各来一遍
enableChannelSplit: false
};
}
// 使用新UI的“重新转换”按钮触发提交
const convertBtn = document.getElementById('convertBtn');
const fileInputNew = document.getElementById('fileInput');
// 绑定文件选择后自动触发转换,避免内联脚本早于 main.js 导致点击丢失
let converting = false;
const triggerConvert = () => { if (converting) { appendLog('已忽略:上一次转换仍在进行中'); return; } convertBtn?.click(); };
fileInputNew?.addEventListener('change', () => {
appendLog('文件已选择,自动触发转换…');
// 简单防抖
clearTimeout(window.__conv_debounce);
window.__conv_debounce = setTimeout(triggerConvert, 50);
});
convertBtn?.addEventListener('click', async (event) => {
if (converting) { appendLog('已忽略:转换进行中'); return; }
converting = true;
event.preventDefault();
resetOutputs();
if (location.protocol === 'file:') { appendLog('当前以 file:// 打开页面,无法向本地代理提交;请访问 http://localhost:6174'); }
const audioUrlInput = { value: "" }; // 新UI不使用 URL
const fileInput = fileInputNew;
const uidInput = { value: "AudioToText" };
const modelNameInput = { value: "bigmodel" };
const sampleRateInput = { value: 16000 };
const bitsInput = { value: 16 };
const channelInput = { value: 1 };
const apiBaseInput = { value: "" };
const apiKeyInput = { value: "" };
const resourceIdInput = { value: "" };
const audioUrl = audioUrlInput.value.trim();
const audioFile = fileInput.files?.[0] ?? null;
if (!audioUrl && !audioFile) {
appendLog("未选择文件,等待提交…");
return;
}
appendLog("检测到文件选择,开始提交识别任务…");
const apiBase = apiBaseInput.value.trim();
const useProxy = apiBase.length === 0;
const submitUrl = useProxy ? proxySubmitEndpoint : `${apiBase}/submit`;
const resultUrl = useProxy ? proxyResultEndpoint : `${apiBase}/query`;
const uid = uidInput.value.trim() || "anonymous";
const modelName = modelNameInput.value.trim() || "bigmodel";
const sampleRate = Number(sampleRateInput.value) || 16000;
const bits = Number(bitsInput.value) || 16;
const channels = Number(channelInput.value) || 1;
const format = audioUrl ? detectAudioFormat(audioUrl) : detectAudioFormat(audioFile.name);
const requestId = (self.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`);
const apiKey = apiKeyInput.value.trim();
const resourceId = resourceIdInput.value.trim();
if (submitButton) submitButton.disabled = true;
if (audioUrl) {
appendLog(`使用音频 URL${audioUrl}`);
} else {
appendLog(`读取文件:${audioFile.name}`);
}
try {
const submitHeaders = createHeaders({ useProxy, apiKey, resourceId, requestId });
const options = readOptions();
let payload;
if (audioUrl) {
const mappedCodec = (["wav","pcm","wave"].includes(format) ? "raw" : (format === "mp3" ? "mp3" : (["m4a","aac"].includes(format) ? "aac" : format)));
const finalRate = (["m4a","aac","mp3"].includes(format) && (!sampleRate || sampleRate < 22050)) ? 44100 : sampleRate;
appendLog(`提交参数source=url, format=${format}, codec=${mappedCodec}, rate=${finalRate}, ch=${channels}`);
payload = {
user: { uid },
audio: { url: audioUrl, format, codec: mappedCodec, rate: finalRate, bits, channel: channels },
request: {
model_name: modelName,
enable_itn: !!options.enableItn,
enable_punc: !!options.enablePunc,
enable_ddc: !!options.enableDdc,
enable_speaker_info: !!options.enableSpeaker,
enable_channel_split: !!options.enableChannelSplit,
show_utterances: !!options.showUtterances,
vad_segment: !!options.vadSegment,
sensitive_words_filter: options.sensitiveWords || ""
}
};
} else {
const base64WithPrefix = await readFileAsBase64(audioFile);
const base64Data = stripDataUriPrefix(base64WithPrefix);
appendLog(`文件编码完成,长度约 ${Math.round(base64Data.length / 1024)} KB`);
payload = buildSubmitPayload({
base64Data,
format,
sampleRate,
bits,
channels,
uid,
modelName,
options
});
// 纠正 codec 映射 + 压缩格式的采样率兜底
const mappedCodec = (["wav","pcm","wave"].includes(format) ? "raw" : (format === "mp3" ? "mp3" : (["m4a","aac"].includes(format) ? "aac" : format)));
const finalRate = (["m4a","aac","mp3"].includes(format) && (!sampleRate || sampleRate < 22050)) ? 44100 : sampleRate;
payload.audio.codec = mappedCodec;
payload.audio.rate = finalRate;
payload.request.enable_itn = !!options.enableItn;
payload.request.enable_punc = !!options.enablePunc;
payload.request.enable_ddc = !!options.enableDdc;
payload.request.enable_speaker_info = !!options.enableSpeaker;
payload.request.enable_channel_split = !!options.enableChannelSplit;
payload.request.show_utterances = !!options.showUtterances;
payload.request.vad_segment = !!options.vadSegment;
payload.request.sensitive_words_filter = options.sensitiveWords || "";
appendLog(`提交参数source=file, format=${format}, codec=${mappedCodec}, rate=${finalRate}, ch=${channels}`);
}
appendLog(`提交请求体:${JSON.stringify(payload)}`);
const submitResponse = await fetch(submitUrl, {
method: "POST",
headers: submitHeaders,
body: JSON.stringify(payload)
}).catch(err => {
appendLog("提交请求未发出,可能没有后端代理或跨域受限");
throw err;
});
if (!submitResponse.ok) {
const errorBody = await submitResponse.text();
appendLog("提交失败:请在本地运行带代理版本,或在代码里配置直连 API 基础地址");
throw new Error(`提交失败HTTP ${submitResponse.status}${errorBody}`);
}
const submitJson = await submitResponse.json();
appendLog(`提交成功:${JSON.stringify(submitJson)}`);
const jobKey = extractJobKey(submitJson);
if (!jobKey) {
throw new Error("未能从提交响应中解析到任务 ID");
}
appendLog(`任务 ID${jobKey}`);
const pollHeaders = createHeaders({ useProxy, apiKey, resourceId, requestId: (self.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`) });
const pollBody = { job_key: jobKey, taskId: jobKey };
const resultJson = await pollJobResult({ url: resultUrl, headers: pollHeaders, body: pollBody, useProxy });
appendLog("任务完成,处理结果如下:");
appendLog(JSON.stringify(resultJson));
// 去重:同一时间窗口(±300ms)、相同文本合并(跨声道去重)
(function dedup(){
const segs = extractSegments(resultJson) || [];
const norm = (ms)=>Math.round((anyToMs(ms)||0)/300);
const seen = new Set();
const filtered = [];
for (const s of segs){
const start = anyToMs(s.start_ms ?? s.start_time ?? s.start) ?? 0;
const end = anyToMs(s.end_ms ?? s.end_time ?? s.end) ?? 0;
const key = `${norm(start)}|${norm(end)}|${(s.text||s.transcript||'').trim()}`;
if (seen.has(key)) continue;
seen.add(key);
filtered.push(s);
}
if (!resultJson.data) resultJson.data = {};
if (!resultJson.data.result) resultJson.data.result = {};
resultJson.data.result.segments = filtered;
})();
lastResultJson = resultJson;
renderInNewUI(lastResultJson);
// 停止计时
if (window.startAnalysisTimer && window.startAnalysisTimer._timer) { clearInterval(window.startAnalysisTimer._timer); window.startAnalysisTimer._timer=null; }
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
appendLog(`发生错误:${message}`);
if (transcriptElement) transcriptElement.value = message;
} finally {
converting = false;
// 新UI无提交按钮禁用逻辑
}
});

BIN
doubao-asr-demo/node_modules/.DS_Store generated vendored Normal file

Binary file not shown.

1
doubao-asr-demo/node_modules/.bin/mime generated vendored Symbolic link
View File

@ -0,0 +1 @@
../mime/cli.js

996
doubao-asr-demo/node_modules/.package-lock.json generated vendored Normal file
View File

@ -0,0 +1,996 @@
{
"name": "doubao-asr-demo",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/accepts": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
"integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
"license": "MIT",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
"license": "MIT"
},
"node_modules/body-parser": {
"version": "1.20.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
"integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.13.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"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",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
"integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
"license": "MIT",
"dependencies": {
"safe-buffer": "5.2.1"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/content-type": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
"integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
"integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==",
"license": "MIT"
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"license": "MIT",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"license": "MIT",
"dependencies": {
"ms": "2.0.0"
}
},
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/destroy": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
"license": "MIT",
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
}
},
"node_modules/dotenv": {
"version": "17.2.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
"integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
"license": "MIT"
},
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
"license": "MIT"
},
"node_modules/etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/eventemitter3": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz",
"integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==",
"license": "MIT"
},
"node_modules/express": {
"version": "4.21.2",
"resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
"integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
"license": "MIT",
"dependencies": {
"accepts": "~1.3.8",
"array-flatten": "1.1.1",
"body-parser": "1.20.3",
"content-disposition": "0.5.4",
"content-type": "~1.0.4",
"cookie": "0.7.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "2.0.0",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "1.3.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"merge-descriptors": "1.0.3",
"methods": "~1.1.2",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.12",
"proxy-addr": "~2.0.7",
"qs": "6.13.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.2.1",
"send": "0.19.0",
"serve-static": "1.16.2",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
},
"engines": {
"node": ">= 0.10.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
}
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/finalhandler": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
"integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
"license": "MIT",
"dependencies": {
"debug": "2.6.9",
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"on-finished": "2.4.1",
"parseurl": "~1.3.3",
"statuses": "2.0.1",
"unpipe": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"license": "MIT",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
"integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
"license": "MIT",
"dependencies": {
"depd": "2.0.0",
"inherits": "2.0.4",
"setprototypeof": "1.2.0",
"statuses": "2.0.1",
"toidentifier": "1.0.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/http-proxy": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz",
"integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==",
"license": "MIT",
"dependencies": {
"eventemitter3": "^4.0.0",
"follow-redirects": "^1.0.0",
"requires-port": "^1.0.0"
},
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/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/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"license": "ISC"
},
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
"license": "MIT",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/merge-descriptors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
"integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
"license": "MIT",
"bin": {
"mime": "cli.js"
},
"engines": {
"node": ">=4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"deprecated": "Use your platform's native DOMException instead",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"license": "MIT",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/object-inspect": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
"integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"license": "MIT",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/path-to-regexp": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
"integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
"license": "MIT"
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
"integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
"license": "MIT",
"dependencies": {
"forwarded": "0.2.0",
"ipaddr.js": "1.9.1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/qs": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
"license": "BSD-3-Clause",
"dependencies": {
"side-channel": "^1.0.6"
},
"engines": {
"node": ">=0.6"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
"integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
"license": "MIT",
"dependencies": {
"bytes": "3.1.2",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/requires-port": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
"license": "MIT"
},
"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==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
"license": "MIT"
},
"node_modules/send": {
"version": "0.19.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
"integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
"license": "MIT",
"dependencies": {
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "2.0.0",
"mime": "1.6.0",
"ms": "2.1.3",
"on-finished": "2.4.1",
"range-parser": "~1.2.1",
"statuses": "2.0.1"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/send/node_modules/encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/send/node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/serve-static": {
"version": "1.16.2",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
"integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
"license": "MIT",
"dependencies": {
"encodeurl": "~2.0.0",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.19.0"
},
"engines": {
"node": ">= 0.8.0"
}
},
"node_modules/setprototypeof": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
"license": "ISC"
},
"node_modules/side-channel": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
"side-channel-list": "^1.0.0",
"side-channel-map": "^1.0.1",
"side-channel-weakmap": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-list": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-map": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/side-channel-weakmap": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"license": "MIT",
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.5",
"object-inspect": "^1.13.3",
"side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
"integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"license": "MIT",
"engines": {
"node": ">=0.6"
}
},
"node_modules/type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"license": "MIT",
"dependencies": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
"license": "MIT",
"engines": {
"node": ">= 0.4.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"license": "MIT",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"license": "MIT",
"engines": {
"node": ">= 8"
}
}
}
}

243
doubao-asr-demo/node_modules/accepts/HISTORY.md generated vendored Normal file
View File

@ -0,0 +1,243 @@
1.3.8 / 2022-02-02
==================
* deps: mime-types@~2.1.34
- deps: mime-db@~1.51.0
* deps: negotiator@0.6.3
1.3.7 / 2019-04-29
==================
* deps: negotiator@0.6.2
- Fix sorting charset, encoding, and language with extra parameters
1.3.6 / 2019-04-28
==================
* deps: mime-types@~2.1.24
- deps: mime-db@~1.40.0
1.3.5 / 2018-02-28
==================
* deps: mime-types@~2.1.18
- deps: mime-db@~1.33.0
1.3.4 / 2017-08-22
==================
* deps: mime-types@~2.1.16
- deps: mime-db@~1.29.0
1.3.3 / 2016-05-02
==================
* deps: mime-types@~2.1.11
- deps: mime-db@~1.23.0
* deps: negotiator@0.6.1
- perf: improve `Accept` parsing speed
- perf: improve `Accept-Charset` parsing speed
- perf: improve `Accept-Encoding` parsing speed
- perf: improve `Accept-Language` parsing speed
1.3.2 / 2016-03-08
==================
* deps: mime-types@~2.1.10
- Fix extension of `application/dash+xml`
- Update primary extension for `audio/mp4`
- deps: mime-db@~1.22.0
1.3.1 / 2016-01-19
==================
* deps: mime-types@~2.1.9
- deps: mime-db@~1.21.0
1.3.0 / 2015-09-29
==================
* deps: mime-types@~2.1.7
- deps: mime-db@~1.19.0
* deps: negotiator@0.6.0
- Fix including type extensions in parameters in `Accept` parsing
- Fix parsing `Accept` parameters with quoted equals
- Fix parsing `Accept` parameters with quoted semicolons
- Lazy-load modules from main entry point
- perf: delay type concatenation until needed
- perf: enable strict mode
- perf: hoist regular expressions
- perf: remove closures getting spec properties
- perf: remove a closure from media type parsing
- perf: remove property delete from media type parsing
1.2.13 / 2015-09-06
===================
* deps: mime-types@~2.1.6
- deps: mime-db@~1.18.0
1.2.12 / 2015-07-30
===================
* deps: mime-types@~2.1.4
- deps: mime-db@~1.16.0
1.2.11 / 2015-07-16
===================
* deps: mime-types@~2.1.3
- deps: mime-db@~1.15.0
1.2.10 / 2015-07-01
===================
* deps: mime-types@~2.1.2
- deps: mime-db@~1.14.0
1.2.9 / 2015-06-08
==================
* deps: mime-types@~2.1.1
- perf: fix deopt during mapping
1.2.8 / 2015-06-07
==================
* deps: mime-types@~2.1.0
- deps: mime-db@~1.13.0
* perf: avoid argument reassignment & argument slice
* perf: avoid negotiator recursive construction
* perf: enable strict mode
* perf: remove unnecessary bitwise operator
1.2.7 / 2015-05-10
==================
* deps: negotiator@0.5.3
- Fix media type parameter matching to be case-insensitive
1.2.6 / 2015-05-07
==================
* deps: mime-types@~2.0.11
- deps: mime-db@~1.9.1
* deps: negotiator@0.5.2
- Fix comparing media types with quoted values
- Fix splitting media types with quoted commas
1.2.5 / 2015-03-13
==================
* deps: mime-types@~2.0.10
- deps: mime-db@~1.8.0
1.2.4 / 2015-02-14
==================
* Support Node.js 0.6
* deps: mime-types@~2.0.9
- deps: mime-db@~1.7.0
* deps: negotiator@0.5.1
- Fix preference sorting to be stable for long acceptable lists
1.2.3 / 2015-01-31
==================
* deps: mime-types@~2.0.8
- deps: mime-db@~1.6.0
1.2.2 / 2014-12-30
==================
* deps: mime-types@~2.0.7
- deps: mime-db@~1.5.0
1.2.1 / 2014-12-30
==================
* deps: mime-types@~2.0.5
- deps: mime-db@~1.3.1
1.2.0 / 2014-12-19
==================
* deps: negotiator@0.5.0
- Fix list return order when large accepted list
- Fix missing identity encoding when q=0 exists
- Remove dynamic building of Negotiator class
1.1.4 / 2014-12-10
==================
* deps: mime-types@~2.0.4
- deps: mime-db@~1.3.0
1.1.3 / 2014-11-09
==================
* deps: mime-types@~2.0.3
- deps: mime-db@~1.2.0
1.1.2 / 2014-10-14
==================
* deps: negotiator@0.4.9
- Fix error when media type has invalid parameter
1.1.1 / 2014-09-28
==================
* deps: mime-types@~2.0.2
- deps: mime-db@~1.1.0
* deps: negotiator@0.4.8
- Fix all negotiations to be case-insensitive
- Stable sort preferences of same quality according to client order
1.1.0 / 2014-09-02
==================
* update `mime-types`
1.0.7 / 2014-07-04
==================
* Fix wrong type returned from `type` when match after unknown extension
1.0.6 / 2014-06-24
==================
* deps: negotiator@0.4.7
1.0.5 / 2014-06-20
==================
* fix crash when unknown extension given
1.0.4 / 2014-06-19
==================
* use `mime-types`
1.0.3 / 2014-06-11
==================
* deps: negotiator@0.4.6
- Order by specificity when quality is the same
1.0.2 / 2014-05-29
==================
* Fix interpretation when header not in request
* deps: pin negotiator@0.4.5
1.0.1 / 2014-01-18
==================
* Identity encoding isn't always acceptable
* deps: negotiator@~0.4.0
1.0.0 / 2013-12-27
==================
* Genesis

23
doubao-asr-demo/node_modules/accepts/LICENSE generated vendored Normal file
View File

@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2015 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

140
doubao-asr-demo/node_modules/accepts/README.md generated vendored Normal file
View File

@ -0,0 +1,140 @@
# accepts
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Higher level content negotiation based on [negotiator](https://www.npmjs.com/package/negotiator).
Extracted from [koa](https://www.npmjs.com/package/koa) for general use.
In addition to negotiator, it allows:
- Allows types as an array or arguments list, ie `(['text/html', 'application/json'])`
as well as `('text/html', 'application/json')`.
- Allows type shorthands such as `json`.
- Returns `false` when no types match
- Treats non-existent headers as `*`
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install accepts
```
## API
```js
var accepts = require('accepts')
```
### accepts(req)
Create a new `Accepts` object for the given `req`.
#### .charset(charsets)
Return the first accepted charset. If nothing in `charsets` is accepted,
then `false` is returned.
#### .charsets()
Return the charsets that the request accepts, in the order of the client's
preference (most preferred first).
#### .encoding(encodings)
Return the first accepted encoding. If nothing in `encodings` is accepted,
then `false` is returned.
#### .encodings()
Return the encodings that the request accepts, in the order of the client's
preference (most preferred first).
#### .language(languages)
Return the first accepted language. If nothing in `languages` is accepted,
then `false` is returned.
#### .languages()
Return the languages that the request accepts, in the order of the client's
preference (most preferred first).
#### .type(types)
Return the first accepted type (and it is returned as the same text as what
appears in the `types` array). If nothing in `types` is accepted, then `false`
is returned.
The `types` array can contain full MIME types or file extensions. Any value
that is not a full MIME types is passed to `require('mime-types').lookup`.
#### .types()
Return the types that the request accepts, in the order of the client's
preference (most preferred first).
## Examples
### Simple type negotiation
This simple example shows how to use `accepts` to return a different typed
respond body based on what the client wants to accept. The server lists it's
preferences in order and will get back the best match between the client and
server.
```js
var accepts = require('accepts')
var http = require('http')
function app (req, res) {
var accept = accepts(req)
// the order of this list is significant; should be server preferred order
switch (accept.type(['json', 'html'])) {
case 'json':
res.setHeader('Content-Type', 'application/json')
res.write('{"hello":"world!"}')
break
case 'html':
res.setHeader('Content-Type', 'text/html')
res.write('<b>hello, world!</b>')
break
default:
// the fallback is text/plain, so no need to specify it above
res.setHeader('Content-Type', 'text/plain')
res.write('hello, world!')
break
}
res.end()
}
http.createServer(app).listen(3000)
```
You can test this out with the cURL program:
```sh
curl -I -H'Accept: text/html' http://localhost:3000/
```
## License
[MIT](LICENSE)
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/accepts/master
[coveralls-url]: https://coveralls.io/r/jshttp/accepts?branch=master
[github-actions-ci-image]: https://badgen.net/github/checks/jshttp/accepts/master?label=ci
[github-actions-ci-url]: https://github.com/jshttp/accepts/actions/workflows/ci.yml
[node-version-image]: https://badgen.net/npm/node/accepts
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/accepts
[npm-url]: https://npmjs.org/package/accepts
[npm-version-image]: https://badgen.net/npm/v/accepts

238
doubao-asr-demo/node_modules/accepts/index.js generated vendored Normal file
View File

@ -0,0 +1,238 @@
/*!
* accepts
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var Negotiator = require('negotiator')
var mime = require('mime-types')
/**
* Module exports.
* @public
*/
module.exports = Accepts
/**
* Create a new Accepts object for the given req.
*
* @param {object} req
* @public
*/
function Accepts (req) {
if (!(this instanceof Accepts)) {
return new Accepts(req)
}
this.headers = req.headers
this.negotiator = new Negotiator(req)
}
/**
* Check if the given `type(s)` is acceptable, returning
* the best match when true, otherwise `undefined`, in which
* case you should respond with 406 "Not Acceptable".
*
* The `type` value may be a single mime type string
* such as "application/json", the extension name
* such as "json" or an array `["json", "html", "text/plain"]`. When a list
* or array is given the _best_ match, if any is returned.
*
* Examples:
*
* // Accept: text/html
* this.types('html');
* // => "html"
*
* // Accept: text/*, application/json
* this.types('html');
* // => "html"
* this.types('text/html');
* // => "text/html"
* this.types('json', 'text');
* // => "json"
* this.types('application/json');
* // => "application/json"
*
* // Accept: text/*, application/json
* this.types('image/png');
* this.types('png');
* // => undefined
*
* // Accept: text/*;q=.5, application/json
* this.types(['html', 'json']);
* this.types('html', 'json');
* // => "json"
*
* @param {String|Array} types...
* @return {String|Array|Boolean}
* @public
*/
Accepts.prototype.type =
Accepts.prototype.types = function (types_) {
var types = types_
// support flattened arguments
if (types && !Array.isArray(types)) {
types = new Array(arguments.length)
for (var i = 0; i < types.length; i++) {
types[i] = arguments[i]
}
}
// no types, return all requested types
if (!types || types.length === 0) {
return this.negotiator.mediaTypes()
}
// no accept header, return first given type
if (!this.headers.accept) {
return types[0]
}
var mimes = types.map(extToMime)
var accepts = this.negotiator.mediaTypes(mimes.filter(validMime))
var first = accepts[0]
return first
? types[mimes.indexOf(first)]
: false
}
/**
* Return accepted encodings or best fit based on `encodings`.
*
* Given `Accept-Encoding: gzip, deflate`
* an array sorted by quality is returned:
*
* ['gzip', 'deflate']
*
* @param {String|Array} encodings...
* @return {String|Array}
* @public
*/
Accepts.prototype.encoding =
Accepts.prototype.encodings = function (encodings_) {
var encodings = encodings_
// support flattened arguments
if (encodings && !Array.isArray(encodings)) {
encodings = new Array(arguments.length)
for (var i = 0; i < encodings.length; i++) {
encodings[i] = arguments[i]
}
}
// no encodings, return all requested encodings
if (!encodings || encodings.length === 0) {
return this.negotiator.encodings()
}
return this.negotiator.encodings(encodings)[0] || false
}
/**
* Return accepted charsets or best fit based on `charsets`.
*
* Given `Accept-Charset: utf-8, iso-8859-1;q=0.2, utf-7;q=0.5`
* an array sorted by quality is returned:
*
* ['utf-8', 'utf-7', 'iso-8859-1']
*
* @param {String|Array} charsets...
* @return {String|Array}
* @public
*/
Accepts.prototype.charset =
Accepts.prototype.charsets = function (charsets_) {
var charsets = charsets_
// support flattened arguments
if (charsets && !Array.isArray(charsets)) {
charsets = new Array(arguments.length)
for (var i = 0; i < charsets.length; i++) {
charsets[i] = arguments[i]
}
}
// no charsets, return all requested charsets
if (!charsets || charsets.length === 0) {
return this.negotiator.charsets()
}
return this.negotiator.charsets(charsets)[0] || false
}
/**
* Return accepted languages or best fit based on `langs`.
*
* Given `Accept-Language: en;q=0.8, es, pt`
* an array sorted by quality is returned:
*
* ['es', 'pt', 'en']
*
* @param {String|Array} langs...
* @return {Array|String}
* @public
*/
Accepts.prototype.lang =
Accepts.prototype.langs =
Accepts.prototype.language =
Accepts.prototype.languages = function (languages_) {
var languages = languages_
// support flattened arguments
if (languages && !Array.isArray(languages)) {
languages = new Array(arguments.length)
for (var i = 0; i < languages.length; i++) {
languages[i] = arguments[i]
}
}
// no languages, return all requested languages
if (!languages || languages.length === 0) {
return this.negotiator.languages()
}
return this.negotiator.languages(languages)[0] || false
}
/**
* Convert extnames to mime.
*
* @param {String} type
* @return {String}
* @private
*/
function extToMime (type) {
return type.indexOf('/') === -1
? mime.lookup(type)
: type
}
/**
* Check if mime is valid.
*
* @param {String} type
* @return {String}
* @private
*/
function validMime (type) {
return typeof type === 'string'
}

47
doubao-asr-demo/node_modules/accepts/package.json generated vendored Normal file
View File

@ -0,0 +1,47 @@
{
"name": "accepts",
"description": "Higher-level content negotiation",
"version": "1.3.8",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
],
"license": "MIT",
"repository": "jshttp/accepts",
"dependencies": {
"mime-types": "~2.1.34",
"negotiator": "0.6.3"
},
"devDependencies": {
"deep-equal": "1.0.1",
"eslint": "7.32.0",
"eslint-config-standard": "14.1.1",
"eslint-plugin-import": "2.25.4",
"eslint-plugin-markdown": "2.2.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.3.1",
"eslint-plugin-standard": "4.1.0",
"mocha": "9.2.0",
"nyc": "15.1.0"
},
"files": [
"LICENSE",
"HISTORY.md",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
},
"keywords": [
"content",
"negotiation",
"accept",
"accepts"
]
}

21
doubao-asr-demo/node_modules/array-flatten/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

43
doubao-asr-demo/node_modules/array-flatten/README.md generated vendored Normal file
View File

@ -0,0 +1,43 @@
# Array Flatten
[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]
[![Build status][travis-image]][travis-url]
[![Test coverage][coveralls-image]][coveralls-url]
> Flatten an array of nested arrays into a single flat array. Accepts an optional depth.
## Installation
```
npm install array-flatten --save
```
## Usage
```javascript
var flatten = require('array-flatten')
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9])
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9]
flatten([1, [2, [3, [4, [5], 6], 7], 8], 9], 2)
//=> [1, 2, 3, [4, [5], 6], 7, 8, 9]
(function () {
flatten(arguments) //=> [1, 2, 3]
})(1, [2, 3])
```
## License
MIT
[npm-image]: https://img.shields.io/npm/v/array-flatten.svg?style=flat
[npm-url]: https://npmjs.org/package/array-flatten
[downloads-image]: https://img.shields.io/npm/dm/array-flatten.svg?style=flat
[downloads-url]: https://npmjs.org/package/array-flatten
[travis-image]: https://img.shields.io/travis/blakeembrey/array-flatten.svg?style=flat
[travis-url]: https://travis-ci.org/blakeembrey/array-flatten
[coveralls-image]: https://img.shields.io/coveralls/blakeembrey/array-flatten.svg?style=flat
[coveralls-url]: https://coveralls.io/r/blakeembrey/array-flatten?branch=master

View File

@ -0,0 +1,64 @@
'use strict'
/**
* Expose `arrayFlatten`.
*/
module.exports = arrayFlatten
/**
* Recursive flatten function with depth.
*
* @param {Array} array
* @param {Array} result
* @param {Number} depth
* @return {Array}
*/
function flattenWithDepth (array, result, depth) {
for (var i = 0; i < array.length; i++) {
var value = array[i]
if (depth > 0 && Array.isArray(value)) {
flattenWithDepth(value, result, depth - 1)
} else {
result.push(value)
}
}
return result
}
/**
* Recursive flatten function. Omitting depth is slightly faster.
*
* @param {Array} array
* @param {Array} result
* @return {Array}
*/
function flattenForever (array, result) {
for (var i = 0; i < array.length; i++) {
var value = array[i]
if (Array.isArray(value)) {
flattenForever(value, result)
} else {
result.push(value)
}
}
return result
}
/**
* Flatten an array, with the ability to define a depth.
*
* @param {Array} array
* @param {Number} depth
* @return {Array}
*/
function arrayFlatten (array, depth) {
if (depth == null) {
return flattenForever(array, [])
}
return flattenWithDepth(array, [], depth)
}

View File

@ -0,0 +1,39 @@
{
"name": "array-flatten",
"version": "1.1.1",
"description": "Flatten an array of nested arrays into a single flat array",
"main": "array-flatten.js",
"files": [
"array-flatten.js",
"LICENSE"
],
"scripts": {
"test": "istanbul cover _mocha -- -R spec"
},
"repository": {
"type": "git",
"url": "git://github.com/blakeembrey/array-flatten.git"
},
"keywords": [
"array",
"flatten",
"arguments",
"depth"
],
"author": {
"name": "Blake Embrey",
"email": "hello@blakeembrey.com",
"url": "http://blakeembrey.me"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/blakeembrey/array-flatten/issues"
},
"homepage": "https://github.com/blakeembrey/array-flatten",
"devDependencies": {
"istanbul": "^0.3.13",
"mocha": "^2.2.4",
"pre-commit": "^1.0.7",
"standard": "^3.7.3"
}
}

672
doubao-asr-demo/node_modules/body-parser/HISTORY.md generated vendored Normal file
View File

@ -0,0 +1,672 @@
1.20.3 / 2024-09-10
===================
* deps: qs@6.13.0
* add `depth` option to customize the depth level in the parser
* IMPORTANT: The default `depth` level for parsing URL-encoded data is now `32` (previously was `Infinity`)
1.20.2 / 2023-02-21
===================
* Fix strict json error message on Node.js 19+
* deps: content-type@~1.0.5
- perf: skip value escaping when unnecessary
* deps: raw-body@2.5.2
1.20.1 / 2022-10-06
===================
* deps: qs@6.11.0
* perf: remove unnecessary object clone
1.20.0 / 2022-04-02
===================
* Fix error message for json parse whitespace in `strict`
* Fix internal error when inflated body exceeds limit
* Prevent loss of async hooks context
* Prevent hanging when request already read
* deps: depd@2.0.0
- Replace internal `eval` usage with `Function` constructor
- Use instance methods on `process` to check for listeners
* deps: http-errors@2.0.0
- deps: depd@2.0.0
- deps: statuses@2.0.1
* deps: on-finished@2.4.1
* deps: qs@6.10.3
* deps: raw-body@2.5.1
- deps: http-errors@2.0.0
1.19.2 / 2022-02-15
===================
* deps: bytes@3.1.2
* deps: qs@6.9.7
* Fix handling of `__proto__` keys
* deps: raw-body@2.4.3
- deps: bytes@3.1.2
1.19.1 / 2021-12-10
===================
* deps: bytes@3.1.1
* deps: http-errors@1.8.1
- deps: inherits@2.0.4
- deps: toidentifier@1.0.1
- deps: setprototypeof@1.2.0
* deps: qs@6.9.6
* deps: raw-body@2.4.2
- deps: bytes@3.1.1
- deps: http-errors@1.8.1
* deps: safe-buffer@5.2.1
* deps: type-is@~1.6.18
1.19.0 / 2019-04-25
===================
* deps: bytes@3.1.0
- Add petabyte (`pb`) support
* deps: http-errors@1.7.2
- Set constructor name when possible
- deps: setprototypeof@1.1.1
- deps: statuses@'>= 1.5.0 < 2'
* deps: iconv-lite@0.4.24
- Added encoding MIK
* deps: qs@6.7.0
- Fix parsing array brackets after index
* deps: raw-body@2.4.0
- deps: bytes@3.1.0
- deps: http-errors@1.7.2
- deps: iconv-lite@0.4.24
* deps: type-is@~1.6.17
- deps: mime-types@~2.1.24
- perf: prevent internal `throw` on invalid type
1.18.3 / 2018-05-14
===================
* Fix stack trace for strict json parse error
* deps: depd@~1.1.2
- perf: remove argument reassignment
* deps: http-errors@~1.6.3
- deps: depd@~1.1.2
- deps: setprototypeof@1.1.0
- deps: statuses@'>= 1.3.1 < 2'
* deps: iconv-lite@0.4.23
- Fix loading encoding with year appended
- Fix deprecation warnings on Node.js 10+
* deps: qs@6.5.2
* deps: raw-body@2.3.3
- deps: http-errors@1.6.3
- deps: iconv-lite@0.4.23
* deps: type-is@~1.6.16
- deps: mime-types@~2.1.18
1.18.2 / 2017-09-22
===================
* deps: debug@2.6.9
* perf: remove argument reassignment
1.18.1 / 2017-09-12
===================
* deps: content-type@~1.0.4
- perf: remove argument reassignment
- perf: skip parameter parsing when no parameters
* deps: iconv-lite@0.4.19
- Fix ISO-8859-1 regression
- Update Windows-1255
* deps: qs@6.5.1
- Fix parsing & compacting very deep objects
* deps: raw-body@2.3.2
- deps: iconv-lite@0.4.19
1.18.0 / 2017-09-08
===================
* Fix JSON strict violation error to match native parse error
* Include the `body` property on verify errors
* Include the `type` property on all generated errors
* Use `http-errors` to set status code on errors
* deps: bytes@3.0.0
* deps: debug@2.6.8
* deps: depd@~1.1.1
- Remove unnecessary `Buffer` loading
* deps: http-errors@~1.6.2
- deps: depd@1.1.1
* deps: iconv-lite@0.4.18
- Add support for React Native
- Add a warning if not loaded as utf-8
- Fix CESU-8 decoding in Node.js 8
- Improve speed of ISO-8859-1 encoding
* deps: qs@6.5.0
* deps: raw-body@2.3.1
- Use `http-errors` for standard emitted errors
- deps: bytes@3.0.0
- deps: iconv-lite@0.4.18
- perf: skip buffer decoding on overage chunk
* perf: prevent internal `throw` when missing charset
1.17.2 / 2017-05-17
===================
* deps: debug@2.6.7
- Fix `DEBUG_MAX_ARRAY_LENGTH`
- deps: ms@2.0.0
* deps: type-is@~1.6.15
- deps: mime-types@~2.1.15
1.17.1 / 2017-03-06
===================
* deps: qs@6.4.0
- Fix regression parsing keys starting with `[`
1.17.0 / 2017-03-01
===================
* deps: http-errors@~1.6.1
- Make `message` property enumerable for `HttpError`s
- deps: setprototypeof@1.0.3
* deps: qs@6.3.1
- Fix compacting nested arrays
1.16.1 / 2017-02-10
===================
* deps: debug@2.6.1
- Fix deprecation messages in WebStorm and other editors
- Undeprecate `DEBUG_FD` set to `1` or `2`
1.16.0 / 2017-01-17
===================
* deps: debug@2.6.0
- Allow colors in workers
- Deprecated `DEBUG_FD` environment variable
- Fix error when running under React Native
- Use same color for same namespace
- deps: ms@0.7.2
* deps: http-errors@~1.5.1
- deps: inherits@2.0.3
- deps: setprototypeof@1.0.2
- deps: statuses@'>= 1.3.1 < 2'
* deps: iconv-lite@0.4.15
- Added encoding MS-31J
- Added encoding MS-932
- Added encoding MS-936
- Added encoding MS-949
- Added encoding MS-950
- Fix GBK/GB18030 handling of Euro character
* deps: qs@6.2.1
- Fix array parsing from skipping empty values
* deps: raw-body@~2.2.0
- deps: iconv-lite@0.4.15
* deps: type-is@~1.6.14
- deps: mime-types@~2.1.13
1.15.2 / 2016-06-19
===================
* deps: bytes@2.4.0
* deps: content-type@~1.0.2
- perf: enable strict mode
* deps: http-errors@~1.5.0
- Use `setprototypeof` module to replace `__proto__` setting
- deps: statuses@'>= 1.3.0 < 2'
- perf: enable strict mode
* deps: qs@6.2.0
* deps: raw-body@~2.1.7
- deps: bytes@2.4.0
- perf: remove double-cleanup on happy path
* deps: type-is@~1.6.13
- deps: mime-types@~2.1.11
1.15.1 / 2016-05-05
===================
* deps: bytes@2.3.0
- Drop partial bytes on all parsed units
- Fix parsing byte string that looks like hex
* deps: raw-body@~2.1.6
- deps: bytes@2.3.0
* deps: type-is@~1.6.12
- deps: mime-types@~2.1.10
1.15.0 / 2016-02-10
===================
* deps: http-errors@~1.4.0
- Add `HttpError` export, for `err instanceof createError.HttpError`
- deps: inherits@2.0.1
- deps: statuses@'>= 1.2.1 < 2'
* deps: qs@6.1.0
* deps: type-is@~1.6.11
- deps: mime-types@~2.1.9
1.14.2 / 2015-12-16
===================
* deps: bytes@2.2.0
* deps: iconv-lite@0.4.13
* deps: qs@5.2.0
* deps: raw-body@~2.1.5
- deps: bytes@2.2.0
- deps: iconv-lite@0.4.13
* deps: type-is@~1.6.10
- deps: mime-types@~2.1.8
1.14.1 / 2015-09-27
===================
* Fix issue where invalid charset results in 400 when `verify` used
* deps: iconv-lite@0.4.12
- Fix CESU-8 decoding in Node.js 4.x
* deps: raw-body@~2.1.4
- Fix masking critical errors from `iconv-lite`
- deps: iconv-lite@0.4.12
* deps: type-is@~1.6.9
- deps: mime-types@~2.1.7
1.14.0 / 2015-09-16
===================
* Fix JSON strict parse error to match syntax errors
* Provide static `require` analysis in `urlencoded` parser
* deps: depd@~1.1.0
- Support web browser loading
* deps: qs@5.1.0
* deps: raw-body@~2.1.3
- Fix sync callback when attaching data listener causes sync read
* deps: type-is@~1.6.8
- Fix type error when given invalid type to match against
- deps: mime-types@~2.1.6
1.13.3 / 2015-07-31
===================
* deps: type-is@~1.6.6
- deps: mime-types@~2.1.4
1.13.2 / 2015-07-05
===================
* deps: iconv-lite@0.4.11
* deps: qs@4.0.0
- Fix dropping parameters like `hasOwnProperty`
- Fix user-visible incompatibilities from 3.1.0
- Fix various parsing edge cases
* deps: raw-body@~2.1.2
- Fix error stack traces to skip `makeError`
- deps: iconv-lite@0.4.11
* deps: type-is@~1.6.4
- deps: mime-types@~2.1.2
- perf: enable strict mode
- perf: remove argument reassignment
1.13.1 / 2015-06-16
===================
* deps: qs@2.4.2
- Downgraded from 3.1.0 because of user-visible incompatibilities
1.13.0 / 2015-06-14
===================
* Add `statusCode` property on `Error`s, in addition to `status`
* Change `type` default to `application/json` for JSON parser
* Change `type` default to `application/x-www-form-urlencoded` for urlencoded parser
* Provide static `require` analysis
* Use the `http-errors` module to generate errors
* deps: bytes@2.1.0
- Slight optimizations
* deps: iconv-lite@0.4.10
- The encoding UTF-16 without BOM now defaults to UTF-16LE when detection fails
- Leading BOM is now removed when decoding
* deps: on-finished@~2.3.0
- Add defined behavior for HTTP `CONNECT` requests
- Add defined behavior for HTTP `Upgrade` requests
- deps: ee-first@1.1.1
* deps: qs@3.1.0
- Fix dropping parameters like `hasOwnProperty`
- Fix various parsing edge cases
- Parsed object now has `null` prototype
* deps: raw-body@~2.1.1
- Use `unpipe` module for unpiping requests
- deps: iconv-lite@0.4.10
* deps: type-is@~1.6.3
- deps: mime-types@~2.1.1
- perf: reduce try block size
- perf: remove bitwise operations
* perf: enable strict mode
* perf: remove argument reassignment
* perf: remove delete call
1.12.4 / 2015-05-10
===================
* deps: debug@~2.2.0
* deps: qs@2.4.2
- Fix allowing parameters like `constructor`
* deps: on-finished@~2.2.1
* deps: raw-body@~2.0.1
- Fix a false-positive when unpiping in Node.js 0.8
- deps: bytes@2.0.1
* deps: type-is@~1.6.2
- deps: mime-types@~2.0.11
1.12.3 / 2015-04-15
===================
* Slight efficiency improvement when not debugging
* deps: depd@~1.0.1
* deps: iconv-lite@0.4.8
- Add encoding alias UNICODE-1-1-UTF-7
* deps: raw-body@1.3.4
- Fix hanging callback if request aborts during read
- deps: iconv-lite@0.4.8
1.12.2 / 2015-03-16
===================
* deps: qs@2.4.1
- Fix error when parameter `hasOwnProperty` is present
1.12.1 / 2015-03-15
===================
* deps: debug@~2.1.3
- Fix high intensity foreground color for bold
- deps: ms@0.7.0
* deps: type-is@~1.6.1
- deps: mime-types@~2.0.10
1.12.0 / 2015-02-13
===================
* add `debug` messages
* accept a function for the `type` option
* use `content-type` to parse `Content-Type` headers
* deps: iconv-lite@0.4.7
- Gracefully support enumerables on `Object.prototype`
* deps: raw-body@1.3.3
- deps: iconv-lite@0.4.7
* deps: type-is@~1.6.0
- fix argument reassignment
- fix false-positives in `hasBody` `Transfer-Encoding` check
- support wildcard for both type and subtype (`*/*`)
- deps: mime-types@~2.0.9
1.11.0 / 2015-01-30
===================
* make internal `extended: true` depth limit infinity
* deps: type-is@~1.5.6
- deps: mime-types@~2.0.8
1.10.2 / 2015-01-20
===================
* deps: iconv-lite@0.4.6
- Fix rare aliases of single-byte encodings
* deps: raw-body@1.3.2
- deps: iconv-lite@0.4.6
1.10.1 / 2015-01-01
===================
* deps: on-finished@~2.2.0
* deps: type-is@~1.5.5
- deps: mime-types@~2.0.7
1.10.0 / 2014-12-02
===================
* make internal `extended: true` array limit dynamic
1.9.3 / 2014-11-21
==================
* deps: iconv-lite@0.4.5
- Fix Windows-31J and X-SJIS encoding support
* deps: qs@2.3.3
- Fix `arrayLimit` behavior
* deps: raw-body@1.3.1
- deps: iconv-lite@0.4.5
* deps: type-is@~1.5.3
- deps: mime-types@~2.0.3
1.9.2 / 2014-10-27
==================
* deps: qs@2.3.2
- Fix parsing of mixed objects and values
1.9.1 / 2014-10-22
==================
* deps: on-finished@~2.1.1
- Fix handling of pipelined requests
* deps: qs@2.3.0
- Fix parsing of mixed implicit and explicit arrays
* deps: type-is@~1.5.2
- deps: mime-types@~2.0.2
1.9.0 / 2014-09-24
==================
* include the charset in "unsupported charset" error message
* include the encoding in "unsupported content encoding" error message
* deps: depd@~1.0.0
1.8.4 / 2014-09-23
==================
* fix content encoding to be case-insensitive
1.8.3 / 2014-09-19
==================
* deps: qs@2.2.4
- Fix issue with object keys starting with numbers truncated
1.8.2 / 2014-09-15
==================
* deps: depd@0.4.5
1.8.1 / 2014-09-07
==================
* deps: media-typer@0.3.0
* deps: type-is@~1.5.1
1.8.0 / 2014-09-05
==================
* make empty-body-handling consistent between chunked requests
- empty `json` produces `{}`
- empty `raw` produces `new Buffer(0)`
- empty `text` produces `''`
- empty `urlencoded` produces `{}`
* deps: qs@2.2.3
- Fix issue where first empty value in array is discarded
* deps: type-is@~1.5.0
- fix `hasbody` to be true for `content-length: 0`
1.7.0 / 2014-09-01
==================
* add `parameterLimit` option to `urlencoded` parser
* change `urlencoded` extended array limit to 100
* respond with 413 when over `parameterLimit` in `urlencoded`
1.6.7 / 2014-08-29
==================
* deps: qs@2.2.2
- Remove unnecessary cloning
1.6.6 / 2014-08-27
==================
* deps: qs@2.2.0
- Array parsing fix
- Performance improvements
1.6.5 / 2014-08-16
==================
* deps: on-finished@2.1.0
1.6.4 / 2014-08-14
==================
* deps: qs@1.2.2
1.6.3 / 2014-08-10
==================
* deps: qs@1.2.1
1.6.2 / 2014-08-07
==================
* deps: qs@1.2.0
- Fix parsing array of objects
1.6.1 / 2014-08-06
==================
* deps: qs@1.1.0
- Accept urlencoded square brackets
- Accept empty values in implicit array notation
1.6.0 / 2014-08-05
==================
* deps: qs@1.0.2
- Complete rewrite
- Limits array length to 20
- Limits object depth to 5
- Limits parameters to 1,000
1.5.2 / 2014-07-27
==================
* deps: depd@0.4.4
- Work-around v8 generating empty stack traces
1.5.1 / 2014-07-26
==================
* deps: depd@0.4.3
- Fix exception when global `Error.stackTraceLimit` is too low
1.5.0 / 2014-07-20
==================
* deps: depd@0.4.2
- Add `TRACE_DEPRECATION` environment variable
- Remove non-standard grey color from color output
- Support `--no-deprecation` argument
- Support `--trace-deprecation` argument
* deps: iconv-lite@0.4.4
- Added encoding UTF-7
* deps: raw-body@1.3.0
- deps: iconv-lite@0.4.4
- Added encoding UTF-7
- Fix `Cannot switch to old mode now` error on Node.js 0.10+
* deps: type-is@~1.3.2
1.4.3 / 2014-06-19
==================
* deps: type-is@1.3.1
- fix global variable leak
1.4.2 / 2014-06-19
==================
* deps: type-is@1.3.0
- improve type parsing
1.4.1 / 2014-06-19
==================
* fix urlencoded extended deprecation message
1.4.0 / 2014-06-19
==================
* add `text` parser
* add `raw` parser
* check accepted charset in content-type (accepts utf-8)
* check accepted encoding in content-encoding (accepts identity)
* deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed
* deprecate `urlencoded()` without provided `extended` option
* lazy-load urlencoded parsers
* parsers split into files for reduced mem usage
* support gzip and deflate bodies
- set `inflate: false` to turn off
* deps: raw-body@1.2.2
- Support all encodings from `iconv-lite`
1.3.1 / 2014-06-11
==================
* deps: type-is@1.2.1
- Switch dependency from mime to mime-types@1.0.0
1.3.0 / 2014-05-31
==================
* add `extended` option to urlencoded parser
1.2.2 / 2014-05-27
==================
* deps: raw-body@1.1.6
- assert stream encoding on node.js 0.8
- assert stream encoding on node.js < 0.10.6
- deps: bytes@1
1.2.1 / 2014-05-26
==================
* invoke `next(err)` after request fully read
- prevents hung responses and socket hang ups
1.2.0 / 2014-05-11
==================
* add `verify` option
* deps: type-is@1.2.0
- support suffix matching
1.1.2 / 2014-05-11
==================
* improve json parser speed
1.1.1 / 2014-05-11
==================
* fix repeated limit parsing with every request
1.1.0 / 2014-05-10
==================
* add `type` option
* deps: pin for safety and consistency
1.0.2 / 2014-04-14
==================
* use `type-is` module
1.0.1 / 2014-03-20
==================
* lower default limits to 100kb

23
doubao-asr-demo/node_modules/body-parser/LICENSE generated vendored Normal file
View File

@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

476
doubao-asr-demo/node_modules/body-parser/README.md generated vendored Normal file
View File

@ -0,0 +1,476 @@
# body-parser
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Build Status][ci-image]][ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![OpenSSF Scorecard Badge][ossf-scorecard-badge]][ossf-scorecard-visualizer]
Node.js body parsing middleware.
Parse incoming request bodies in a middleware before your handlers, available
under the `req.body` property.
**Note** As `req.body`'s shape is based on user-controlled input, all
properties and values in this object are untrusted and should be validated
before trusting. For example, `req.body.foo.toString()` may fail in multiple
ways, for example the `foo` property may not be there or may not be a string,
and `toString` may not be a function and instead a string or other user input.
[Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/).
_This does not handle multipart bodies_, due to their complex and typically
large nature. For multipart bodies, you may be interested in the following
modules:
* [busboy](https://www.npmjs.org/package/busboy#readme) and
[connect-busboy](https://www.npmjs.org/package/connect-busboy#readme)
* [multiparty](https://www.npmjs.org/package/multiparty#readme) and
[connect-multiparty](https://www.npmjs.org/package/connect-multiparty#readme)
* [formidable](https://www.npmjs.org/package/formidable#readme)
* [multer](https://www.npmjs.org/package/multer#readme)
This module provides the following parsers:
* [JSON body parser](#bodyparserjsonoptions)
* [Raw body parser](#bodyparserrawoptions)
* [Text body parser](#bodyparsertextoptions)
* [URL-encoded form body parser](#bodyparserurlencodedoptions)
Other body parsers you might be interested in:
- [body](https://www.npmjs.org/package/body#readme)
- [co-body](https://www.npmjs.org/package/co-body#readme)
## Installation
```sh
$ npm install body-parser
```
## API
```js
var bodyParser = require('body-parser')
```
The `bodyParser` object exposes various factories to create middlewares. All
middlewares will populate the `req.body` property with the parsed body when
the `Content-Type` request header matches the `type` option, or an empty
object (`{}`) if there was no body to parse, the `Content-Type` was not matched,
or an error occurred.
The various errors returned by this module are described in the
[errors section](#errors).
### bodyParser.json([options])
Returns middleware that only parses `json` and only looks at requests where
the `Content-Type` header matches the `type` option. This parser accepts any
Unicode encoding of the body and supports automatic inflation of `gzip` and
`deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`).
#### Options
The `json` function takes an optional `options` object that may contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### reviver
The `reviver` option is passed directly to `JSON.parse` as the second
argument. You can find more information on this argument
[in the MDN documentation about JSON.parse](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse#Example.3A_Using_the_reviver_parameter).
##### strict
When set to `true`, will only accept arrays and objects; when `false` will
accept anything `JSON.parse` accepts. Defaults to `true`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a string, array of strings, or a function. If not a
function, `type` option is passed directly to the
[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
be an extension name (like `json`), a mime type (like `application/json`), or
a mime type with a wildcard (like `*/*` or `*/json`). If a function, the `type`
option is called as `fn(req)` and the request is parsed if it returns a truthy
value. Defaults to `application/json`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.raw([options])
Returns middleware that parses all bodies as a `Buffer` and only looks at
requests where the `Content-Type` header matches the `type` option. This
parser supports automatic inflation of `gzip` and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a `Buffer` object
of the body.
#### Options
The `raw` function takes an optional `options` object that may contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a string, array of strings, or a function.
If not a function, `type` option is passed directly to the
[type-is](https://www.npmjs.org/package/type-is#readme) library and this
can be an extension name (like `bin`), a mime type (like
`application/octet-stream`), or a mime type with a wildcard (like `*/*` or
`application/*`). If a function, the `type` option is called as `fn(req)`
and the request is parsed if it returns a truthy value. Defaults to
`application/octet-stream`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.text([options])
Returns middleware that parses all bodies as a string and only looks at
requests where the `Content-Type` header matches the `type` option. This
parser supports automatic inflation of `gzip` and `deflate` encodings.
A new `body` string containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This will be a string of the
body.
#### Options
The `text` function takes an optional `options` object that may contain any of
the following keys:
##### defaultCharset
Specify the default character set for the text content if the charset is not
specified in the `Content-Type` header of the request. Defaults to `utf-8`.
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a string, array of strings, or a function. If not
a function, `type` option is passed directly to the
[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
be an extension name (like `txt`), a mime type (like `text/plain`), or a mime
type with a wildcard (like `*/*` or `text/*`). If a function, the `type`
option is called as `fn(req)` and the request is parsed if it returns a
truthy value. Defaults to `text/plain`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
### bodyParser.urlencoded([options])
Returns middleware that only parses `urlencoded` bodies and only looks at
requests where the `Content-Type` header matches the `type` option. This
parser accepts only UTF-8 encoding of the body and supports automatic
inflation of `gzip` and `deflate` encodings.
A new `body` object containing the parsed data is populated on the `request`
object after the middleware (i.e. `req.body`). This object will contain
key-value pairs, where the value can be a string or array (when `extended` is
`false`), or any type (when `extended` is `true`).
#### Options
The `urlencoded` function takes an optional `options` object that may contain
any of the following keys:
##### extended
The `extended` option allows to choose between parsing the URL-encoded data
with the `querystring` library (when `false`) or the `qs` library (when
`true`). The "extended" syntax allows for rich objects and arrays to be
encoded into the URL-encoded format, allowing for a JSON-like experience
with URL-encoded. For more information, please
[see the qs library](https://www.npmjs.org/package/qs#readme).
Defaults to `true`, but using the default has been deprecated. Please
research into the difference between `qs` and `querystring` and choose the
appropriate setting.
##### inflate
When set to `true`, then deflated (compressed) bodies will be inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number, then the value
specifies the number of bytes; if it is a string, the value is passed to the
[bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults
to `'100kb'`.
##### parameterLimit
The `parameterLimit` option controls the maximum number of parameters that
are allowed in the URL-encoded data. If a request contains more parameters
than this value, a 413 will be returned to the client. Defaults to `1000`.
##### type
The `type` option is used to determine what media type the middleware will
parse. This option can be a string, array of strings, or a function. If not
a function, `type` option is passed directly to the
[type-is](https://www.npmjs.org/package/type-is#readme) library and this can
be an extension name (like `urlencoded`), a mime type (like
`application/x-www-form-urlencoded`), or a mime type with a wildcard (like
`*/x-www-form-urlencoded`). If a function, the `type` option is called as
`fn(req)` and the request is parsed if it returns a truthy value. Defaults
to `application/x-www-form-urlencoded`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding` is the
encoding of the request. The parsing can be aborted by throwing an error.
#### depth
The `depth` option is used to configure the maximum depth of the `qs` library when `extended` is `true`. This allows you to limit the amount of keys that are parsed and can be useful to prevent certain types of abuse. Defaults to `32`. It is recommended to keep this value as low as possible.
## Errors
The middlewares provided by this module create errors using the
[`http-errors` module](https://www.npmjs.com/package/http-errors). The errors
will typically have a `status`/`statusCode` property that contains the suggested
HTTP response code, an `expose` property to determine if the `message` property
should be displayed to the client, a `type` property to determine the type of
error without matching against the `message`, and a `body` property containing
the read body, if available.
The following are the common errors created, though any error can come through
for various reasons.
### content encoding unsupported
This error will occur when the request had a `Content-Encoding` header that
contained an encoding but the "inflation" option was set to `false`. The
`status` property is set to `415`, the `type` property is set to
`'encoding.unsupported'`, and the `charset` property will be set to the
encoding that is unsupported.
### entity parse failed
This error will occur when the request contained an entity that could not be
parsed by the middleware. The `status` property is set to `400`, the `type`
property is set to `'entity.parse.failed'`, and the `body` property is set to
the entity value that failed parsing.
### entity verify failed
This error will occur when the request contained an entity that could not be
failed verification by the defined `verify` option. The `status` property is
set to `403`, the `type` property is set to `'entity.verify.failed'`, and the
`body` property is set to the entity value that failed verification.
### request aborted
This error will occur when the request is aborted by the client before reading
the body has finished. The `received` property will be set to the number of
bytes received before the request was aborted and the `expected` property is
set to the number of expected bytes. The `status` property is set to `400`
and `type` property is set to `'request.aborted'`.
### request entity too large
This error will occur when the request body's size is larger than the "limit"
option. The `limit` property will be set to the byte limit and the `length`
property will be set to the request body's length. The `status` property is
set to `413` and the `type` property is set to `'entity.too.large'`.
### request size did not match content length
This error will occur when the request's length did not match the length from
the `Content-Length` header. This typically occurs when the request is malformed,
typically when the `Content-Length` header was calculated based on characters
instead of bytes. The `status` property is set to `400` and the `type` property
is set to `'request.size.invalid'`.
### stream encoding should not be set
This error will occur when something called the `req.setEncoding` method prior
to this middleware. This module operates directly on bytes only and you cannot
call `req.setEncoding` when using this module. The `status` property is set to
`500` and the `type` property is set to `'stream.encoding.set'`.
### stream is not readable
This error will occur when the request is no longer readable when this middleware
attempts to read it. This typically means something other than a middleware from
this module read the request body already and the middleware was also configured to
read the same request. The `status` property is set to `500` and the `type`
property is set to `'stream.not.readable'`.
### too many parameters
This error will occur when the content of the request exceeds the configured
`parameterLimit` for the `urlencoded` parser. The `status` property is set to
`413` and the `type` property is set to `'parameters.too.many'`.
### unsupported charset "BOGUS"
This error will occur when the request had a charset parameter in the
`Content-Type` header, but the `iconv-lite` module does not support it OR the
parser does not support it. The charset is contained in the message as well
as in the `charset` property. The `status` property is set to `415`, the
`type` property is set to `'charset.unsupported'`, and the `charset` property
is set to the charset that is unsupported.
### unsupported content encoding "bogus"
This error will occur when the request had a `Content-Encoding` header that
contained an unsupported encoding. The encoding is contained in the message
as well as in the `encoding` property. The `status` property is set to `415`,
the `type` property is set to `'encoding.unsupported'`, and the `encoding`
property is set to the encoding that is unsupported.
### The input exceeded the depth
This error occurs when using `bodyParser.urlencoded` with the `extended` property set to `true` and the input exceeds the configured `depth` option. The `status` property is set to `400`. It is recommended to review the `depth` option and evaluate if it requires a higher value. When the `depth` option is set to `32` (default value), the error will not be thrown.
## Examples
### Express/Connect top-level generic
This example demonstrates adding a generic JSON and URL-encoded parser as a
top-level middleware, which will parse the bodies of all incoming requests.
This is the simplest setup.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
})
```
### Express route-specific
This example demonstrates adding body parsers specifically to the routes that
need them. In general, this is the most recommended way to use body-parser with
Express.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// create application/json parser
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
res.send('welcome, ' + req.body.username)
})
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
// create user in req.body
})
```
### Change accepted type for parsers
All the parsers accept a `type` option which allows you to change the
`Content-Type` that the middleware will parse.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }))
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }))
```
## License
[MIT](LICENSE)
[ci-image]: https://badgen.net/github/checks/expressjs/body-parser/master?label=ci
[ci-url]: https://github.com/expressjs/body-parser/actions/workflows/ci.yml
[coveralls-image]: https://badgen.net/coveralls/c/github/expressjs/body-parser/master
[coveralls-url]: https://coveralls.io/r/expressjs/body-parser?branch=master
[node-version-image]: https://badgen.net/npm/node/body-parser
[node-version-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/body-parser
[npm-url]: https://npmjs.org/package/body-parser
[npm-version-image]: https://badgen.net/npm/v/body-parser
[ossf-scorecard-badge]: https://api.scorecard.dev/projects/github.com/expressjs/body-parser/badge
[ossf-scorecard-visualizer]: https://ossf.github.io/scorecard-visualizer/#/projects/github.com/expressjs/body-parser

25
doubao-asr-demo/node_modules/body-parser/SECURITY.md generated vendored Normal file
View File

@ -0,0 +1,25 @@
# Security Policies and Procedures
## Reporting a Bug
The Express team and community take all security bugs seriously. Thank you
for improving the security of Express. We appreciate your efforts and
responsible disclosure and will make every effort to acknowledge your
contributions.
Report security bugs by emailing the current owner(s) of `body-parser`. This
information can be found in the npm registry using the command
`npm owner ls body-parser`.
If unsure or unable to get the information from the above, open an issue
in the [project issue tracker](https://github.com/expressjs/body-parser/issues)
asking for the current contact information.
To ensure the timely response to your report, please ensure that the entirety
of the report is contained within the email body and not solely behind a web
link or an attachment.
At least one owner will acknowledge your email within 48 hours, and will send a
more detailed response within 48 hours indicating the next steps in handling
your report. After the initial reply to your report, the owners will
endeavor to keep you informed of the progress towards a fix and full
announcement, and may ask for additional information or guidance.

156
doubao-asr-demo/node_modules/body-parser/index.js generated vendored Normal file
View File

@ -0,0 +1,156 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var deprecate = require('depd')('body-parser')
/**
* Cache of loaded parsers.
* @private
*/
var parsers = Object.create(null)
/**
* @typedef Parsers
* @type {function}
* @property {function} json
* @property {function} raw
* @property {function} text
* @property {function} urlencoded
*/
/**
* Module exports.
* @type {Parsers}
*/
exports = module.exports = deprecate.function(bodyParser,
'bodyParser: use individual json/urlencoded middlewares')
/**
* JSON parser.
* @public
*/
Object.defineProperty(exports, 'json', {
configurable: true,
enumerable: true,
get: createParserGetter('json')
})
/**
* Raw parser.
* @public
*/
Object.defineProperty(exports, 'raw', {
configurable: true,
enumerable: true,
get: createParserGetter('raw')
})
/**
* Text parser.
* @public
*/
Object.defineProperty(exports, 'text', {
configurable: true,
enumerable: true,
get: createParserGetter('text')
})
/**
* URL-encoded parser.
* @public
*/
Object.defineProperty(exports, 'urlencoded', {
configurable: true,
enumerable: true,
get: createParserGetter('urlencoded')
})
/**
* Create a middleware to parse json and urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @deprecated
* @public
*/
function bodyParser (options) {
// use default type for parsers
var opts = Object.create(options || null, {
type: {
configurable: true,
enumerable: true,
value: undefined,
writable: true
}
})
var _urlencoded = exports.urlencoded(opts)
var _json = exports.json(opts)
return function bodyParser (req, res, next) {
_json(req, res, function (err) {
if (err) return next(err)
_urlencoded(req, res, next)
})
}
}
/**
* Create a getter for loading a parser.
* @private
*/
function createParserGetter (name) {
return function get () {
return loadParser(name)
}
}
/**
* Load a parser module.
* @private
*/
function loadParser (parserName) {
var parser = parsers[parserName]
if (parser !== undefined) {
return parser
}
// this uses a switch for static require analysis
switch (parserName) {
case 'json':
parser = require('./lib/types/json')
break
case 'raw':
parser = require('./lib/types/raw')
break
case 'text':
parser = require('./lib/types/text')
break
case 'urlencoded':
parser = require('./lib/types/urlencoded')
break
}
// store to prevent invoking require()
return (parsers[parserName] = parser)
}

205
doubao-asr-demo/node_modules/body-parser/lib/read.js generated vendored Normal file
View File

@ -0,0 +1,205 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var createError = require('http-errors')
var destroy = require('destroy')
var getBody = require('raw-body')
var iconv = require('iconv-lite')
var onFinished = require('on-finished')
var unpipe = require('unpipe')
var zlib = require('zlib')
/**
* Module exports.
*/
module.exports = read
/**
* Read a request into a buffer and parse.
*
* @param {object} req
* @param {object} res
* @param {function} next
* @param {function} parse
* @param {function} debug
* @param {object} options
* @private
*/
function read (req, res, next, parse, debug, options) {
var length
var opts = options
var stream
// flag as parsed
req._body = true
// read options
var encoding = opts.encoding !== null
? opts.encoding
: null
var verify = opts.verify
try {
// get the content stream
stream = contentstream(req, debug, opts.inflate)
length = stream.length
stream.length = undefined
} catch (err) {
return next(err)
}
// set raw-body options
opts.length = length
opts.encoding = verify
? null
: encoding
// assert charset is supported
if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
charset: encoding.toLowerCase(),
type: 'charset.unsupported'
}))
}
// read body
debug('read body')
getBody(stream, opts, function (error, body) {
if (error) {
var _error
if (error.type === 'encoding.unsupported') {
// echo back charset
_error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
charset: encoding.toLowerCase(),
type: 'charset.unsupported'
})
} else {
// set status code on error
_error = createError(400, error)
}
// unpipe from stream and destroy
if (stream !== req) {
unpipe(req)
destroy(stream, true)
}
// read off entire request
dump(req, function onfinished () {
next(createError(400, _error))
})
return
}
// verify
if (verify) {
try {
debug('verify body')
verify(req, res, body, encoding)
} catch (err) {
next(createError(403, err, {
body: body,
type: err.type || 'entity.verify.failed'
}))
return
}
}
// parse
var str = body
try {
debug('parse body')
str = typeof body !== 'string' && encoding !== null
? iconv.decode(body, encoding)
: body
req.body = parse(str)
} catch (err) {
next(createError(400, err, {
body: str,
type: err.type || 'entity.parse.failed'
}))
return
}
next()
})
}
/**
* Get the content stream of the request.
*
* @param {object} req
* @param {function} debug
* @param {boolean} [inflate=true]
* @return {object}
* @api private
*/
function contentstream (req, debug, inflate) {
var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
var length = req.headers['content-length']
var stream
debug('content-encoding "%s"', encoding)
if (inflate === false && encoding !== 'identity') {
throw createError(415, 'content encoding unsupported', {
encoding: encoding,
type: 'encoding.unsupported'
})
}
switch (encoding) {
case 'deflate':
stream = zlib.createInflate()
debug('inflate body')
req.pipe(stream)
break
case 'gzip':
stream = zlib.createGunzip()
debug('gunzip body')
req.pipe(stream)
break
case 'identity':
stream = req
stream.length = length
break
default:
throw createError(415, 'unsupported content encoding "' + encoding + '"', {
encoding: encoding,
type: 'encoding.unsupported'
})
}
return stream
}
/**
* Dump the contents of a request.
*
* @param {object} req
* @param {function} callback
* @api private
*/
function dump (req, callback) {
if (onFinished.isFinished(req)) {
callback(null)
} else {
onFinished(req, callback)
req.resume()
}
}

View File

@ -0,0 +1,247 @@
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:json')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = json
/**
* RegExp to match the first non-space in a string.
*
* Allowed whitespace is defined in RFC 7159:
*
* ws = *(
* %x20 / ; Space
* %x09 / ; Horizontal tab
* %x0A / ; Line feed or New line
* %x0D ) ; Carriage return
*/
var FIRST_CHAR_REGEXP = /^[\x20\x09\x0a\x0d]*([^\x20\x09\x0a\x0d])/ // eslint-disable-line no-control-regex
var JSON_SYNTAX_CHAR = '#'
var JSON_SYNTAX_REGEXP = /#+/g
/**
* Create a middleware to parse JSON bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function json (options) {
var opts = options || {}
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var inflate = opts.inflate !== false
var reviver = opts.reviver
var strict = opts.strict !== false
var type = opts.type || 'application/json'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (body) {
if (body.length === 0) {
// special-case empty json body, as it's a common client-side mistake
// TODO: maybe make this configurable or part of "strict" option
return {}
}
if (strict) {
var first = firstchar(body)
if (first !== '{' && first !== '[') {
debug('strict violation')
throw createStrictSyntaxError(body, first)
}
}
try {
debug('parse json')
return JSON.parse(body, reviver)
} catch (e) {
throw normalizeJsonSyntaxError(e, {
message: e.message,
stack: e.stack
})
}
}
return function jsonParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// assert charset per RFC 7159 sec 8.1
var charset = getCharset(req) || 'utf-8'
if (charset.slice(0, 4) !== 'utf-') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset,
type: 'charset.unsupported'
}))
return
}
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Create strict violation syntax error matching native error.
*
* @param {string} str
* @param {string} char
* @return {Error}
* @private
*/
function createStrictSyntaxError (str, char) {
var index = str.indexOf(char)
var partial = ''
if (index !== -1) {
partial = str.substring(0, index) + JSON_SYNTAX_CHAR
for (var i = index + 1; i < str.length; i++) {
partial += JSON_SYNTAX_CHAR
}
}
try {
JSON.parse(partial); /* istanbul ignore next */ throw new SyntaxError('strict violation')
} catch (e) {
return normalizeJsonSyntaxError(e, {
message: e.message.replace(JSON_SYNTAX_REGEXP, function (placeholder) {
return str.substring(index, index + placeholder.length)
}),
stack: e.stack
})
}
}
/**
* Get the first non-whitespace character in a string.
*
* @param {string} str
* @return {function}
* @private
*/
function firstchar (str) {
var match = FIRST_CHAR_REGEXP.exec(str)
return match
? match[1]
: undefined
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return (contentType.parse(req).parameters.charset || '').toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Normalize a SyntaxError for JSON.parse.
*
* @param {SyntaxError} error
* @param {object} obj
* @return {SyntaxError}
*/
function normalizeJsonSyntaxError (error, obj) {
var keys = Object.getOwnPropertyNames(error)
for (var i = 0; i < keys.length; i++) {
var key = keys[i]
if (key !== 'stack' && key !== 'message') {
delete error[key]
}
}
// replace stack before message for Node.js 0.10 and below
error.stack = obj.stack.replace(error.message, obj.message)
error.message = obj.message
return error
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@ -0,0 +1,101 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var debug = require('debug')('body-parser:raw')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = raw
/**
* Create a middleware to parse raw bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function raw (options) {
var opts = options || {}
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/octet-stream'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (buf) {
return buf
}
return function rawParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// read
read(req, res, next, parse, debug, {
encoding: null,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@ -0,0 +1,121 @@
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var contentType = require('content-type')
var debug = require('debug')('body-parser:text')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = text
/**
* Create a middleware to parse text bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function text (options) {
var opts = options || {}
var defaultCharset = opts.defaultCharset || 'utf-8'
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'text/plain'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (buf) {
return buf
}
return function textParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// get charset
var charset = getCharset(req) || defaultCharset
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return (contentType.parse(req).parameters.charset || '').toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

View File

@ -0,0 +1,307 @@
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:urlencoded')
var deprecate = require('depd')('body-parser')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = urlencoded
/**
* Cache of parser modules.
*/
var parsers = Object.create(null)
/**
* Create a middleware to parse urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function urlencoded (options) {
var opts = options || {}
// notice because option default will flip in next major
if (opts.extended === undefined) {
deprecate('undefined extended: provide extended option')
}
var extended = opts.extended !== false
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/x-www-form-urlencoded'
var verify = opts.verify || false
var depth = typeof opts.depth !== 'number'
? Number(opts.depth || 32)
: opts.depth
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate query parser
var queryparse = extended
? extendedparser(opts)
: simpleparser(opts)
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (body) {
return body.length
? queryparse(body)
: {}
}
return function urlencodedParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// assert charset
var charset = getCharset(req) || 'utf-8'
if (charset !== 'utf-8') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
charset: charset,
type: 'charset.unsupported'
}))
return
}
// read
read(req, res, next, parse, debug, {
debug: debug,
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify,
depth: depth
})
}
}
/**
* Get the extended query parser.
*
* @param {object} options
*/
function extendedparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var depth = typeof options.depth !== 'number'
? Number(options.depth || 32)
: options.depth
var parse = parser('qs')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}
if (isNaN(depth) || depth < 0) {
throw new TypeError('option depth must be a zero or a positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters', {
type: 'parameters.too.many'
})
}
var arrayLimit = Math.max(100, paramCount)
debug('parse extended urlencoding')
try {
return parse(body, {
allowPrototypes: true,
arrayLimit: arrayLimit,
depth: depth,
strictDepth: true,
parameterLimit: parameterLimit
})
} catch (err) {
if (err instanceof RangeError) {
throw createError(400, 'The input exceeded the depth', {
type: 'querystring.parse.rangeError'
})
} else {
throw err
}
}
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return (contentType.parse(req).parameters.charset || '').toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Count the number of parameters, stopping once limit reached
*
* @param {string} body
* @param {number} limit
* @api private
*/
function parameterCount (body, limit) {
var count = 0
var index = 0
while ((index = body.indexOf('&', index)) !== -1) {
count++
index++
if (count === limit) {
return undefined
}
}
return count
}
/**
* Get parser for module name dynamically.
*
* @param {string} name
* @return {function}
* @api private
*/
function parser (name) {
var mod = parsers[name]
if (mod !== undefined) {
return mod.parse
}
// this uses a switch for static require analysis
switch (name) {
case 'qs':
mod = require('qs')
break
case 'querystring':
mod = require('querystring')
break
}
// store to prevent invoking require()
parsers[name] = mod
return mod.parse
}
/**
* Get the simple query parser.
*
* @param {object} options
*/
function simpleparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('querystring')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters', {
type: 'parameters.too.many'
})
}
debug('parse urlencoding')
return parse(body, undefined, undefined, { maxKeys: parameterLimit })
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}

56
doubao-asr-demo/node_modules/body-parser/package.json generated vendored Normal file
View File

@ -0,0 +1,56 @@
{
"name": "body-parser",
"description": "Node.js body parsing middleware",
"version": "1.20.3",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
],
"license": "MIT",
"repository": "expressjs/body-parser",
"dependencies": {
"bytes": "3.1.2",
"content-type": "~1.0.5",
"debug": "2.6.9",
"depd": "2.0.0",
"destroy": "1.2.0",
"http-errors": "2.0.0",
"iconv-lite": "0.4.24",
"on-finished": "2.4.1",
"qs": "6.13.0",
"raw-body": "2.5.2",
"type-is": "~1.6.18",
"unpipe": "1.0.0"
},
"devDependencies": {
"eslint": "8.34.0",
"eslint-config-standard": "14.1.1",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-markdown": "3.0.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-standard": "4.1.0",
"methods": "1.1.2",
"mocha": "10.2.0",
"nyc": "15.1.0",
"safe-buffer": "5.2.1",
"supertest": "6.3.3"
},
"files": [
"lib/",
"LICENSE",
"HISTORY.md",
"SECURITY.md",
"index.js"
],
"engines": {
"node": ">= 0.8",
"npm": "1.2.8000 || >= 1.4.16"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --require test/support/env --reporter spec --check-leaks --bail test/",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}

97
doubao-asr-demo/node_modules/bytes/History.md generated vendored Normal file
View File

@ -0,0 +1,97 @@
3.1.2 / 2022-01-27
==================
* Fix return value for un-parsable strings
3.1.1 / 2021-11-15
==================
* Fix "thousandsSeparator" incorrecting formatting fractional part
3.1.0 / 2019-01-22
==================
* Add petabyte (`pb`) support
3.0.0 / 2017-08-31
==================
* Change "kB" to "KB" in format output
* Remove support for Node.js 0.6
* Remove support for ComponentJS
2.5.0 / 2017-03-24
==================
* Add option "unit"
2.4.0 / 2016-06-01
==================
* Add option "unitSeparator"
2.3.0 / 2016-02-15
==================
* Drop partial bytes on all parsed units
* Fix non-finite numbers to `.format` to return `null`
* Fix parsing byte string that looks like hex
* perf: hoist regular expressions
2.2.0 / 2015-11-13
==================
* add option "decimalPlaces"
* add option "fixedDecimals"
2.1.0 / 2015-05-21
==================
* add `.format` export
* add `.parse` export
2.0.2 / 2015-05-20
==================
* remove map recreation
* remove unnecessary object construction
2.0.1 / 2015-05-07
==================
* fix browserify require
* remove node.extend dependency
2.0.0 / 2015-04-12
==================
* add option "case"
* add option "thousandsSeparator"
* return "null" on invalid parse input
* support proper round-trip: bytes(bytes(num)) === num
* units no longer case sensitive when parsing
1.0.0 / 2014-05-05
==================
* add negative support. fixes #6
0.3.0 / 2014-03-19
==================
* added terabyte support
0.2.1 / 2013-04-01
==================
* add .component
0.2.0 / 2012-10-28
==================
* bytes(200).should.eql('200b')
0.1.0 / 2012-07-04
==================
* add bytes to string conversion [yields]

23
doubao-asr-demo/node_modules/bytes/LICENSE generated vendored Normal file
View File

@ -0,0 +1,23 @@
(The MIT License)
Copyright (c) 2012-2014 TJ Holowaychuk <tj@vision-media.ca>
Copyright (c) 2015 Jed Watson <jed.watson@me.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

152
doubao-asr-demo/node_modules/bytes/Readme.md generated vendored Normal file
View File

@ -0,0 +1,152 @@
# Bytes utility
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][ci-image]][ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Utility to parse a string bytes (ex: `1TB`) to bytes (`1099511627776`) and vice-versa.
## Installation
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```bash
$ npm install bytes
```
## Usage
```js
var bytes = require('bytes');
```
#### bytes(numberstring value, [options]): numberstringnull
Default export function. Delegates to either `bytes.format` or `bytes.parse` based on the type of `value`.
**Arguments**
| Name | Type | Description |
|---------|----------|--------------------|
| value | `number``string` | Number value to format or string value to parse |
| options | `Object` | Conversion options for `format` |
**Returns**
| Name | Type | Description |
|---------|------------------|-------------------------------------------------|
| results | `string``number``null` | Return null upon error. Numeric value in bytes, or string value otherwise. |
**Example**
```js
bytes(1024);
// output: '1KB'
bytes('1KB');
// output: 1024
```
#### bytes.format(number value, [options]): stringnull
Format the given value in bytes into a string. If the value is negative, it is kept as such. If it is a float, it is
rounded.
**Arguments**
| Name | Type | Description |
|---------|----------|--------------------|
| value | `number` | Value in bytes |
| options | `Object` | Conversion options |
**Options**
| Property | Type | Description |
|-------------------|--------|-----------------------------------------------------------------------------------------|
| decimalPlaces | `number``null` | Maximum number of decimal places to include in output. Default value to `2`. |
| fixedDecimals | `boolean``null` | Whether to always display the maximum number of decimal places. Default value to `false` |
| thousandsSeparator | `string``null` | Example of values: `' '`, `','` and `'.'`... Default value to `''`. |
| unit | `string``null` | The unit in which the result will be returned (B/KB/MB/GB/TB). Default value to `''` (which means auto detect). |
| unitSeparator | `string``null` | Separator to use between number and unit. Default value to `''`. |
**Returns**
| Name | Type | Description |
|---------|------------------|-------------------------------------------------|
| results | `string``null` | Return null upon error. String value otherwise. |
**Example**
```js
bytes.format(1024);
// output: '1KB'
bytes.format(1000);
// output: '1000B'
bytes.format(1000, {thousandsSeparator: ' '});
// output: '1 000B'
bytes.format(1024 * 1.7, {decimalPlaces: 0});
// output: '2KB'
bytes.format(1024, {unitSeparator: ' '});
// output: '1 KB'
```
#### bytes.parse(stringnumber value): numbernull
Parse the string value into an integer in bytes. If no unit is given, or `value`
is a number, it is assumed the value is in bytes.
Supported units and abbreviations are as follows and are case-insensitive:
* `b` for bytes
* `kb` for kilobytes
* `mb` for megabytes
* `gb` for gigabytes
* `tb` for terabytes
* `pb` for petabytes
The units are in powers of two, not ten. This means 1kb = 1024b according to this parser.
**Arguments**
| Name | Type | Description |
|---------------|--------|--------------------|
| value | `string``number` | String to parse, or number in bytes. |
**Returns**
| Name | Type | Description |
|---------|-------------|-------------------------|
| results | `number``null` | Return null upon error. Value in bytes otherwise. |
**Example**
```js
bytes.parse('1KB');
// output: 1024
bytes.parse('1024');
// output: 1024
bytes.parse(1024);
// output: 1024
```
## License
[MIT](LICENSE)
[ci-image]: https://badgen.net/github/checks/visionmedia/bytes.js/master?label=ci
[ci-url]: https://github.com/visionmedia/bytes.js/actions?query=workflow%3Aci
[coveralls-image]: https://badgen.net/coveralls/c/github/visionmedia/bytes.js/master
[coveralls-url]: https://coveralls.io/r/visionmedia/bytes.js?branch=master
[downloads-image]: https://badgen.net/npm/dm/bytes
[downloads-url]: https://npmjs.org/package/bytes
[npm-image]: https://badgen.net/npm/v/bytes
[npm-url]: https://npmjs.org/package/bytes

170
doubao-asr-demo/node_modules/bytes/index.js generated vendored Normal file
View File

@ -0,0 +1,170 @@
/*!
* bytes
* Copyright(c) 2012-2014 TJ Holowaychuk
* Copyright(c) 2015 Jed Watson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = bytes;
module.exports.format = format;
module.exports.parse = parse;
/**
* Module variables.
* @private
*/
var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
var map = {
b: 1,
kb: 1 << 10,
mb: 1 << 20,
gb: 1 << 30,
tb: Math.pow(1024, 4),
pb: Math.pow(1024, 5),
};
var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
/**
* Convert the given value in bytes into a string or parse to string to an integer in bytes.
*
* @param {string|number} value
* @param {{
* case: [string],
* decimalPlaces: [number]
* fixedDecimals: [boolean]
* thousandsSeparator: [string]
* unitSeparator: [string]
* }} [options] bytes options.
*
* @returns {string|number|null}
*/
function bytes(value, options) {
if (typeof value === 'string') {
return parse(value);
}
if (typeof value === 'number') {
return format(value, options);
}
return null;
}
/**
* Format the given value in bytes into a string.
*
* If the value is negative, it is kept as such. If it is a float,
* it is rounded.
*
* @param {number} value
* @param {object} [options]
* @param {number} [options.decimalPlaces=2]
* @param {number} [options.fixedDecimals=false]
* @param {string} [options.thousandsSeparator=]
* @param {string} [options.unit=]
* @param {string} [options.unitSeparator=]
*
* @returns {string|null}
* @public
*/
function format(value, options) {
if (!Number.isFinite(value)) {
return null;
}
var mag = Math.abs(value);
var thousandsSeparator = (options && options.thousandsSeparator) || '';
var unitSeparator = (options && options.unitSeparator) || '';
var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2;
var fixedDecimals = Boolean(options && options.fixedDecimals);
var unit = (options && options.unit) || '';
if (!unit || !map[unit.toLowerCase()]) {
if (mag >= map.pb) {
unit = 'PB';
} else if (mag >= map.tb) {
unit = 'TB';
} else if (mag >= map.gb) {
unit = 'GB';
} else if (mag >= map.mb) {
unit = 'MB';
} else if (mag >= map.kb) {
unit = 'KB';
} else {
unit = 'B';
}
}
var val = value / map[unit.toLowerCase()];
var str = val.toFixed(decimalPlaces);
if (!fixedDecimals) {
str = str.replace(formatDecimalsRegExp, '$1');
}
if (thousandsSeparator) {
str = str.split('.').map(function (s, i) {
return i === 0
? s.replace(formatThousandsRegExp, thousandsSeparator)
: s
}).join('.');
}
return str + unitSeparator + unit;
}
/**
* Parse the string value into an integer in bytes.
*
* If no unit is given, it is assumed the value is in bytes.
*
* @param {number|string} val
*
* @returns {number|null}
* @public
*/
function parse(val) {
if (typeof val === 'number' && !isNaN(val)) {
return val;
}
if (typeof val !== 'string') {
return null;
}
// Test if the string passed is valid
var results = parseRegExp.exec(val);
var floatValue;
var unit = 'b';
if (!results) {
// Nothing could be extracted from the given string
floatValue = parseInt(val, 10);
unit = 'b'
} else {
// Retrieve the value and the unit
floatValue = parseFloat(results[1]);
unit = results[4].toLowerCase();
}
if (isNaN(floatValue)) {
return null;
}
return Math.floor(map[unit] * floatValue);
}

42
doubao-asr-demo/node_modules/bytes/package.json generated vendored Normal file
View File

@ -0,0 +1,42 @@
{
"name": "bytes",
"description": "Utility to parse a string bytes to bytes and vice-versa",
"version": "3.1.2",
"author": "TJ Holowaychuk <tj@vision-media.ca> (http://tjholowaychuk.com)",
"contributors": [
"Jed Watson <jed.watson@me.com>",
"Théo FIDRY <theo.fidry@gmail.com>"
],
"license": "MIT",
"keywords": [
"byte",
"bytes",
"utility",
"parse",
"parser",
"convert",
"converter"
],
"repository": "visionmedia/bytes.js",
"devDependencies": {
"eslint": "7.32.0",
"eslint-plugin-markdown": "2.2.1",
"mocha": "9.2.0",
"nyc": "15.1.0"
},
"files": [
"History.md",
"LICENSE",
"Readme.md",
"index.js"
],
"engines": {
"node": ">= 0.8"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --check-leaks --reporter spec",
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test"
}
}

View File

@ -0,0 +1,17 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"func-name-matching": 0,
"id-length": 0,
"new-cap": [2, {
"capIsNewExceptions": [
"GetIntrinsic",
],
}],
"no-extra-parens": 0,
"no-magic-numbers": 0,
},
}

View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/call-bind-apply-helpers
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -0,0 +1,9 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"exclude": [
"coverage",
"test"
]
}

View File

@ -0,0 +1,30 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.0.2](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.1...v1.0.2) - 2025-02-12
### Commits
- [types] improve inferred types [`e6f9586`](https://github.com/ljharb/call-bind-apply-helpers/commit/e6f95860a3c72879cb861a858cdfb8138fbedec1)
- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `@types/tape`, `es-value-fixtures`, `for-each`, `has-strict-mode`, `object-inspect` [`e43d540`](https://github.com/ljharb/call-bind-apply-helpers/commit/e43d5409f97543bfbb11f345d47d8ce4e066d8c1)
## [v1.0.1](https://github.com/ljharb/call-bind-apply-helpers/compare/v1.0.0...v1.0.1) - 2024-12-08
### Commits
- [types] `reflectApply`: fix types [`4efc396`](https://github.com/ljharb/call-bind-apply-helpers/commit/4efc3965351a4f02cc55e836fa391d3d11ef2ef8)
- [Fix] `reflectApply`: oops, Reflect is not a function [`83cc739`](https://github.com/ljharb/call-bind-apply-helpers/commit/83cc7395de6b79b7730bdf092f1436f0b1263c75)
- [Dev Deps] update `@arethetypeswrong/cli` [`80bd5d3`](https://github.com/ljharb/call-bind-apply-helpers/commit/80bd5d3ae58b4f6b6995ce439dd5a1bcb178a940)
## v1.0.0 - 2024-12-05
### Commits
- Initial implementation, tests, readme [`7879629`](https://github.com/ljharb/call-bind-apply-helpers/commit/78796290f9b7430c9934d6f33d94ae9bc89fce04)
- Initial commit [`3f1dc16`](https://github.com/ljharb/call-bind-apply-helpers/commit/3f1dc164afc43285631b114a5f9dd9137b2b952f)
- npm init [`081df04`](https://github.com/ljharb/call-bind-apply-helpers/commit/081df048c312fcee400922026f6e97281200a603)
- Only apps should have lockfiles [`5b9ca0f`](https://github.com/ljharb/call-bind-apply-helpers/commit/5b9ca0fe8101ebfaf309c549caac4e0a017ed930)

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Jordan Harband
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,62 @@
# call-bind-apply-helpers <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][npm-badge-png]][package-url]
Helper functions around Function call/apply/bind, for use in `call-bind`.
The only packages that should likely ever use this package directly are `call-bind` and `get-intrinsic`.
Please use `call-bind` unless you have a very good reason not to.
## Getting started
```sh
npm install --save call-bind-apply-helpers
```
## Usage/Examples
```js
const assert = require('assert');
const callBindBasic = require('call-bind-apply-helpers');
function f(a, b) {
assert.equal(this, 1);
assert.equal(a, 2);
assert.equal(b, 3);
assert.equal(arguments.length, 2);
}
const fBound = callBindBasic([f, 1]);
delete Function.prototype.call;
delete Function.prototype.bind;
fBound(2, 3);
```
## Tests
Clone the repo, `npm install`, and run `npm test`
[package-url]: https://npmjs.org/package/call-bind-apply-helpers
[npm-version-svg]: https://versionbadg.es/ljharb/call-bind-apply-helpers.svg
[deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers.svg
[deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers
[dev-deps-svg]: https://david-dm.org/ljharb/call-bind-apply-helpers/dev-status.svg
[dev-deps-url]: https://david-dm.org/ljharb/call-bind-apply-helpers#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/call-bind-apply-helpers.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/call-bind-apply-helpers.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/call-bind-apply-helpers.svg
[downloads-url]: https://npm-stat.com/charts.html?package=call-bind-apply-helpers
[codecov-image]: https://codecov.io/gh/ljharb/call-bind-apply-helpers/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/ljharb/call-bind-apply-helpers/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/call-bind-apply-helpers
[actions-url]: https://github.com/ljharb/call-bind-apply-helpers/actions

View File

@ -0,0 +1 @@
export = Reflect.apply;

View File

@ -0,0 +1,10 @@
'use strict';
var bind = require('function-bind');
var $apply = require('./functionApply');
var $call = require('./functionCall');
var $reflectApply = require('./reflectApply');
/** @type {import('./actualApply')} */
module.exports = $reflectApply || bind.call($call, $apply);

View File

@ -0,0 +1,19 @@
import actualApply from './actualApply';
type TupleSplitHead<T extends any[], N extends number> = T['length'] extends N
? T
: T extends [...infer R, any]
? TupleSplitHead<R, N>
: never
type TupleSplitTail<T, N extends number, O extends any[] = []> = O['length'] extends N
? T
: T extends [infer F, ...infer R]
? TupleSplitTail<[...R], N, [...O, F]>
: never
type TupleSplit<T extends any[], N extends number> = [TupleSplitHead<T, N>, TupleSplitTail<T, N>]
declare function applyBind(...args: TupleSplit<Parameters<typeof actualApply>, 2>[1]): ReturnType<typeof actualApply>;
export = applyBind;

View File

@ -0,0 +1,10 @@
'use strict';
var bind = require('function-bind');
var $apply = require('./functionApply');
var actualApply = require('./actualApply');
/** @type {import('./applyBind')} */
module.exports = function applyBind() {
return actualApply(bind, $apply, arguments);
};

View File

@ -0,0 +1 @@
export = Function.prototype.apply;

View File

@ -0,0 +1,4 @@
'use strict';
/** @type {import('./functionApply')} */
module.exports = Function.prototype.apply;

View File

@ -0,0 +1 @@
export = Function.prototype.call;

View File

@ -0,0 +1,4 @@
'use strict';
/** @type {import('./functionCall')} */
module.exports = Function.prototype.call;

View File

@ -0,0 +1,64 @@
type RemoveFromTuple<
Tuple extends readonly unknown[],
RemoveCount extends number,
Index extends 1[] = []
> = Index["length"] extends RemoveCount
? Tuple
: Tuple extends [infer First, ...infer Rest]
? RemoveFromTuple<Rest, RemoveCount, [...Index, 1]>
: Tuple;
type ConcatTuples<
Prefix extends readonly unknown[],
Suffix extends readonly unknown[]
> = [...Prefix, ...Suffix];
type ExtractFunctionParams<T> = T extends (this: infer TThis, ...args: infer P extends readonly unknown[]) => infer R
? { thisArg: TThis; params: P; returnType: R }
: never;
type BindFunction<
T extends (this: any, ...args: any[]) => any,
TThis,
TBoundArgs extends readonly unknown[],
ReceiverBound extends boolean
> = ExtractFunctionParams<T> extends {
thisArg: infer OrigThis;
params: infer P extends readonly unknown[];
returnType: infer R;
}
? ReceiverBound extends true
? (...args: RemoveFromTuple<P, Extract<TBoundArgs["length"], number>>) => R extends [OrigThis, ...infer Rest]
? [TThis, ...Rest] // Replace `this` with `thisArg`
: R
: <U, RemainingArgs extends RemoveFromTuple<P, Extract<TBoundArgs["length"], number>>>(
thisArg: U,
...args: RemainingArgs
) => R extends [OrigThis, ...infer Rest]
? [U, ...ConcatTuples<TBoundArgs, Rest>] // Preserve bound args in return type
: R
: never;
declare function callBind<
const T extends (this: any, ...args: any[]) => any,
Extracted extends ExtractFunctionParams<T>,
const TBoundArgs extends Partial<Extracted["params"]> & readonly unknown[],
const TThis extends Extracted["thisArg"]
>(
args: [fn: T, thisArg: TThis, ...boundArgs: TBoundArgs]
): BindFunction<T, TThis, TBoundArgs, true>;
declare function callBind<
const T extends (this: any, ...args: any[]) => any,
Extracted extends ExtractFunctionParams<T>,
const TBoundArgs extends Partial<Extracted["params"]> & readonly unknown[]
>(
args: [fn: T, ...boundArgs: TBoundArgs]
): BindFunction<T, Extracted["thisArg"], TBoundArgs, false>;
declare function callBind<const TArgs extends readonly unknown[]>(
args: [fn: Exclude<TArgs[0], Function>, ...rest: TArgs]
): never;
// export as namespace callBind;
export = callBind;

View File

@ -0,0 +1,15 @@
'use strict';
var bind = require('function-bind');
var $TypeError = require('es-errors/type');
var $call = require('./functionCall');
var $actualApply = require('./actualApply');
/** @type {(args: [Function, thisArg?: unknown, ...args: unknown[]]) => Function} TODO FIXME, find a way to use import('.') */
module.exports = function callBindBasic(args) {
if (args.length < 1 || typeof args[0] !== 'function') {
throw new $TypeError('a function is required');
}
return $actualApply(bind, $call, args);
};

View File

@ -0,0 +1,85 @@
{
"name": "call-bind-apply-helpers",
"version": "1.0.2",
"description": "Helper functions around Function call/apply/bind, for use in `call-bind`",
"main": "index.js",
"exports": {
".": "./index.js",
"./actualApply": "./actualApply.js",
"./applyBind": "./applyBind.js",
"./functionApply": "./functionApply.js",
"./functionCall": "./functionCall.js",
"./reflectApply": "./reflectApply.js",
"./package.json": "./package.json"
},
"scripts": {
"prepack": "npmignore --auto --commentLines=auto",
"prepublish": "not-in-publish || npm run prepublishOnly",
"prepublishOnly": "safe-publish-latest",
"prelint": "evalmd README.md",
"lint": "eslint --ext=.js,.mjs .",
"postlint": "tsc -p . && attw -P",
"pretest": "npm run lint",
"tests-only": "nyc tape 'test/**/*.js'",
"test": "npm run tests-only",
"posttest": "npx npm@'>=10.2' audit --production",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/ljharb/call-bind-apply-helpers.git"
},
"author": "Jordan Harband <ljharb@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/ljharb/call-bind-apply-helpers/issues"
},
"homepage": "https://github.com/ljharb/call-bind-apply-helpers#readme",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.17.3",
"@ljharb/eslint-config": "^21.1.1",
"@ljharb/tsconfig": "^0.2.3",
"@types/for-each": "^0.3.3",
"@types/function-bind": "^1.1.10",
"@types/object-inspect": "^1.13.0",
"@types/tape": "^5.8.1",
"auto-changelog": "^2.5.0",
"encoding": "^0.1.13",
"es-value-fixtures": "^1.7.1",
"eslint": "=8.8.0",
"evalmd": "^0.0.19",
"for-each": "^0.3.5",
"has-strict-mode": "^1.1.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.1",
"nyc": "^10.3.2",
"object-inspect": "^1.13.4",
"safe-publish-latest": "^2.0.0",
"tape": "^5.9.0",
"typescript": "next"
},
"testling": {
"files": "test/index.js"
},
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
},
"publishConfig": {
"ignore": [
".github/workflows"
]
},
"engines": {
"node": ">= 0.4"
}
}

View File

@ -0,0 +1,3 @@
declare const reflectApply: false | typeof Reflect.apply;
export = reflectApply;

View File

@ -0,0 +1,4 @@
'use strict';
/** @type {import('./reflectApply')} */
module.exports = typeof Reflect !== 'undefined' && Reflect && Reflect.apply;

View File

@ -0,0 +1,63 @@
'use strict';
var callBind = require('../');
var hasStrictMode = require('has-strict-mode')();
var forEach = require('for-each');
var inspect = require('object-inspect');
var v = require('es-value-fixtures');
var test = require('tape');
test('callBindBasic', function (t) {
forEach(v.nonFunctions, function (nonFunction) {
t['throws'](
// @ts-expect-error
function () { callBind([nonFunction]); },
TypeError,
inspect(nonFunction) + ' is not a function'
);
});
var sentinel = { sentinel: true };
/** @type {<T, A extends number, B extends number>(this: T, a: A, b: B) => [T | undefined, A, B]} */
var func = function (a, b) {
// eslint-disable-next-line no-invalid-this
return [!hasStrictMode && this === global ? undefined : this, a, b];
};
t.equal(func.length, 2, 'original function length is 2');
/** type {(thisArg: unknown, a: number, b: number) => [unknown, number, number]} */
var bound = callBind([func]);
/** type {((a: number, b: number) => [typeof sentinel, typeof a, typeof b])} */
var boundR = callBind([func, sentinel]);
/** type {((b: number) => [typeof sentinel, number, typeof b])} */
var boundArg = callBind([func, sentinel, /** @type {const} */ (1)]);
// @ts-expect-error
t.deepEqual(bound(), [undefined, undefined, undefined], 'bound func with no args');
// @ts-expect-error
t.deepEqual(func(), [undefined, undefined, undefined], 'unbound func with too few args');
// @ts-expect-error
t.deepEqual(bound(1, 2), [hasStrictMode ? 1 : Object(1), 2, undefined], 'bound func too few args');
// @ts-expect-error
t.deepEqual(boundR(), [sentinel, undefined, undefined], 'bound func with receiver, with too few args');
// @ts-expect-error
t.deepEqual(boundArg(), [sentinel, 1, undefined], 'bound func with receiver and arg, with too few args');
t.deepEqual(func(1, 2), [undefined, 1, 2], 'unbound func with right args');
t.deepEqual(bound(1, 2, 3), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with right args');
t.deepEqual(boundR(1, 2), [sentinel, 1, 2], 'bound func with receiver, with right args');
t.deepEqual(boundArg(2), [sentinel, 1, 2], 'bound func with receiver and arg, with right arg');
// @ts-expect-error
t.deepEqual(func(1, 2, 3), [undefined, 1, 2], 'unbound func with too many args');
// @ts-expect-error
t.deepEqual(bound(1, 2, 3, 4), [hasStrictMode ? 1 : Object(1), 2, 3], 'bound func with too many args');
// @ts-expect-error
t.deepEqual(boundR(1, 2, 3), [sentinel, 1, 2], 'bound func with receiver, with too many args');
// @ts-expect-error
t.deepEqual(boundArg(2, 3), [sentinel, 1, 2], 'bound func with receiver and arg, with too many args');
t.end();
});

View File

@ -0,0 +1,9 @@
{
"extends": "@ljharb/tsconfig",
"compilerOptions": {
"target": "es2021",
},
"exclude": [
"coverage",
],
}

13
doubao-asr-demo/node_modules/call-bound/.eslintrc generated vendored Normal file
View File

@ -0,0 +1,13 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"new-cap": [2, {
"capIsNewExceptions": [
"GetIntrinsic",
],
}],
},
}

View File

@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/call-bound
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

9
doubao-asr-demo/node_modules/call-bound/.nycrc generated vendored Normal file
View File

@ -0,0 +1,9 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"exclude": [
"coverage",
"test"
]
}

42
doubao-asr-demo/node_modules/call-bound/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,42 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.0.4](https://github.com/ljharb/call-bound/compare/v1.0.3...v1.0.4) - 2025-03-03
### Commits
- [types] improve types [`e648922`](https://github.com/ljharb/call-bound/commit/e6489222a9e54f350fbf952ceabe51fd8b6027ff)
- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `@types/tape`, `es-value-fixtures`, `for-each`, `has-strict-mode`, `object-inspect` [`a42a5eb`](https://github.com/ljharb/call-bound/commit/a42a5ebe6c1b54fcdc7997c7dc64fdca9e936719)
- [Deps] update `call-bind-apply-helpers`, `get-intrinsic` [`f529eac`](https://github.com/ljharb/call-bound/commit/f529eac132404c17156bbc23ab2297a25d0f20b8)
## [v1.0.3](https://github.com/ljharb/call-bound/compare/v1.0.2...v1.0.3) - 2024-12-15
### Commits
- [Refactor] use `call-bind-apply-helpers` instead of `call-bind` [`5e0b134`](https://github.com/ljharb/call-bound/commit/5e0b13496df14fb7d05dae9412f088da8d3f75be)
- [Deps] update `get-intrinsic` [`41fc967`](https://github.com/ljharb/call-bound/commit/41fc96732a22c7b7e8f381f93ccc54bb6293be2e)
- [readme] fix example [`79a0137`](https://github.com/ljharb/call-bound/commit/79a0137723f7c6d09c9c05452bbf8d5efb5d6e49)
- [meta] add `sideEffects` flag [`08b07be`](https://github.com/ljharb/call-bound/commit/08b07be7f1c03f67dc6f3cdaf0906259771859f7)
## [v1.0.2](https://github.com/ljharb/call-bound/compare/v1.0.1...v1.0.2) - 2024-12-10
### Commits
- [Dev Deps] update `@arethetypeswrong/cli`, `@ljharb/tsconfig`, `gopd` [`e6a5ffe`](https://github.com/ljharb/call-bound/commit/e6a5ffe849368fe4f74dfd6cdeca1b9baa39e8d5)
- [Deps] update `call-bind`, `get-intrinsic` [`2aeb5b5`](https://github.com/ljharb/call-bound/commit/2aeb5b521dc2b2683d1345c753ea1161de2d1c14)
- [types] improve return type [`1a0c9fe`](https://github.com/ljharb/call-bound/commit/1a0c9fe3114471e7ca1f57d104e2efe713bb4871)
## v1.0.1 - 2024-12-05
### Commits
- Initial implementation, tests, readme, types [`6d94121`](https://github.com/ljharb/call-bound/commit/6d94121a9243602e506334069f7a03189fe3363d)
- Initial commit [`0eae867`](https://github.com/ljharb/call-bound/commit/0eae867334ea025c33e6e91cdecfc9df96680cf9)
- npm init [`71b2479`](https://github.com/ljharb/call-bound/commit/71b2479c6723e0b7d91a6b663613067e98b7b275)
- Only apps should have lockfiles [`c3754a9`](https://github.com/ljharb/call-bound/commit/c3754a949b7f9132b47e2d18c1729889736741eb)
- [actions] skip `npm ls` in node &lt; 10 [`74275a5`](https://github.com/ljharb/call-bound/commit/74275a5186b8caf6309b6b97472bdcb0df4683a8)
- [Dev Deps] add missing peer dep [`1354de8`](https://github.com/ljharb/call-bound/commit/1354de8679413e4ae9c523d85f76fa7a5e032d97)

21
doubao-asr-demo/node_modules/call-bound/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Jordan Harband
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

53
doubao-asr-demo/node_modules/call-bound/README.md generated vendored Normal file
View File

@ -0,0 +1,53 @@
# call-bound <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![github actions][actions-image]][actions-url]
[![coverage][codecov-image]][codecov-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][npm-badge-png]][package-url]
Robust call-bound JavaScript intrinsics, using `call-bind` and `get-intrinsic`.
## Getting started
```sh
npm install --save call-bound
```
## Usage/Examples
```js
const assert = require('assert');
const callBound = require('call-bound');
const slice = callBound('Array.prototype.slice');
delete Function.prototype.call;
delete Function.prototype.bind;
delete Array.prototype.slice;
assert.deepEqual(slice([1, 2, 3, 4], 1, -1), [2, 3]);
```
## Tests
Clone the repo, `npm install`, and run `npm test`
[package-url]: https://npmjs.org/package/call-bound
[npm-version-svg]: https://versionbadg.es/ljharb/call-bound.svg
[deps-svg]: https://david-dm.org/ljharb/call-bound.svg
[deps-url]: https://david-dm.org/ljharb/call-bound
[dev-deps-svg]: https://david-dm.org/ljharb/call-bound/dev-status.svg
[dev-deps-url]: https://david-dm.org/ljharb/call-bound#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/call-bound.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/call-bound.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/call-bound.svg
[downloads-url]: https://npm-stat.com/charts.html?package=call-bound
[codecov-image]: https://codecov.io/gh/ljharb/call-bound/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/ljharb/call-bound/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/call-bound
[actions-url]: https://github.com/ljharb/call-bound/actions

94
doubao-asr-demo/node_modules/call-bound/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,94 @@
type Intrinsic = typeof globalThis;
type IntrinsicName = keyof Intrinsic | `%${keyof Intrinsic}%`;
type IntrinsicPath = IntrinsicName | `${StripPercents<IntrinsicName>}.${string}` | `%${StripPercents<IntrinsicName>}.${string}%`;
type AllowMissing = boolean;
type StripPercents<T extends string> = T extends `%${infer U}%` ? U : T;
type BindMethodPrecise<F> =
F extends (this: infer This, ...args: infer Args) => infer R
? (obj: This, ...args: Args) => R
: F extends {
(this: infer This1, ...args: infer Args1): infer R1;
(this: infer This2, ...args: infer Args2): infer R2
}
? {
(obj: This1, ...args: Args1): R1;
(obj: This2, ...args: Args2): R2
}
: never
// Extract method type from a prototype
type GetPrototypeMethod<T extends keyof typeof globalThis, M extends string> =
(typeof globalThis)[T] extends { prototype: any }
? M extends keyof (typeof globalThis)[T]['prototype']
? (typeof globalThis)[T]['prototype'][M]
: never
: never
// Get static property/method
type GetStaticMember<T extends keyof typeof globalThis, P extends string> =
P extends keyof (typeof globalThis)[T] ? (typeof globalThis)[T][P] : never
// Type that maps string path to actual bound function or value with better precision
type BoundIntrinsic<S extends string> =
S extends `${infer Obj}.prototype.${infer Method}`
? Obj extends keyof typeof globalThis
? BindMethodPrecise<GetPrototypeMethod<Obj, Method & string>>
: unknown
: S extends `${infer Obj}.${infer Prop}`
? Obj extends keyof typeof globalThis
? GetStaticMember<Obj, Prop & string>
: unknown
: unknown
declare function arraySlice<T>(array: readonly T[], start?: number, end?: number): T[];
declare function arraySlice<T>(array: ArrayLike<T>, start?: number, end?: number): T[];
declare function arraySlice<T>(array: IArguments, start?: number, end?: number): T[];
// Special cases for methods that need explicit typing
interface SpecialCases {
'%Object.prototype.isPrototypeOf%': (thisArg: {}, obj: unknown) => boolean;
'%String.prototype.replace%': {
(str: string, searchValue: string | RegExp, replaceValue: string): string;
(str: string, searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string
};
'%Object.prototype.toString%': (obj: {}) => string;
'%Object.prototype.hasOwnProperty%': (obj: {}, v: PropertyKey) => boolean;
'%Array.prototype.slice%': typeof arraySlice;
'%Array.prototype.map%': <T, U>(array: readonly T[], callbackfn: (value: T, index: number, array: readonly T[]) => U, thisArg?: any) => U[];
'%Array.prototype.filter%': <T>(array: readonly T[], predicate: (value: T, index: number, array: readonly T[]) => unknown, thisArg?: any) => T[];
'%Array.prototype.indexOf%': <T>(array: readonly T[], searchElement: T, fromIndex?: number) => number;
'%Function.prototype.apply%': <T, A extends any[], R>(fn: (...args: A) => R, thisArg: any, args: A) => R;
'%Function.prototype.call%': <T, A extends any[], R>(fn: (...args: A) => R, thisArg: any, ...args: A) => R;
'%Function.prototype.bind%': <T, A extends any[], R>(fn: (...args: A) => R, thisArg: any, ...args: A) => (...remainingArgs: A) => R;
'%Promise.prototype.then%': {
<T, R>(promise: Promise<T>, onfulfilled: (value: T) => R | PromiseLike<R>): Promise<R>;
<T, R>(promise: Promise<T>, onfulfilled: ((value: T) => R | PromiseLike<R>) | undefined | null, onrejected: (reason: any) => R | PromiseLike<R>): Promise<R>;
};
'%RegExp.prototype.test%': (regexp: RegExp, str: string) => boolean;
'%RegExp.prototype.exec%': (regexp: RegExp, str: string) => RegExpExecArray | null;
'%Error.prototype.toString%': (error: Error) => string;
'%TypeError.prototype.toString%': (error: TypeError) => string;
'%String.prototype.split%': (
obj: unknown,
splitter: string | RegExp | {
[Symbol.split](string: string, limit?: number): string[];
},
limit?: number | undefined
) => string[];
}
/**
* Returns a bound function for a prototype method, or a value for a static property.
*
* @param name - The name of the intrinsic (e.g. 'Array.prototype.slice')
* @param {AllowMissing} [allowMissing] - Whether to allow missing intrinsics (default: false)
*/
declare function callBound<K extends keyof SpecialCases | StripPercents<keyof SpecialCases>, S extends IntrinsicPath>(name: K, allowMissing?: AllowMissing): SpecialCases[`%${StripPercents<K>}%`];
declare function callBound<K extends keyof SpecialCases | StripPercents<keyof SpecialCases>, S extends IntrinsicPath>(name: S, allowMissing?: AllowMissing): BoundIntrinsic<S>;
export = callBound;

19
doubao-asr-demo/node_modules/call-bound/index.js generated vendored Normal file
View File

@ -0,0 +1,19 @@
'use strict';
var GetIntrinsic = require('get-intrinsic');
var callBindBasic = require('call-bind-apply-helpers');
/** @type {(thisArg: string, searchString: string, position?: number) => number} */
var $indexOf = callBindBasic([GetIntrinsic('%String.prototype.indexOf%')]);
/** @type {import('.')} */
module.exports = function callBoundIntrinsic(name, allowMissing) {
/* eslint no-extra-parens: 0 */
var intrinsic = /** @type {(this: unknown, ...args: unknown[]) => unknown} */ (GetIntrinsic(name, !!allowMissing));
if (typeof intrinsic === 'function' && $indexOf(name, '.prototype.') > -1) {
return callBindBasic(/** @type {const} */ ([intrinsic]));
}
return intrinsic;
};

99
doubao-asr-demo/node_modules/call-bound/package.json generated vendored Normal file
View File

@ -0,0 +1,99 @@
{
"name": "call-bound",
"version": "1.0.4",
"description": "Robust call-bound JavaScript intrinsics, using `call-bind` and `get-intrinsic`.",
"main": "index.js",
"exports": {
".": "./index.js",
"./package.json": "./package.json"
},
"sideEffects": false,
"scripts": {
"prepack": "npmignore --auto --commentLines=auto",
"prepublish": "not-in-publish || npm run prepublishOnly",
"prepublishOnly": "safe-publish-latest",
"prelint": "evalmd README.md",
"lint": "eslint --ext=.js,.mjs .",
"postlint": "tsc -p . && attw -P",
"pretest": "npm run lint",
"tests-only": "nyc tape 'test/**/*.js'",
"test": "npm run tests-only",
"posttest": "npx npm@'>=10.2' audit --production",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"repository": {
"type": "git",
"url": "git+https://github.com/ljharb/call-bound.git"
},
"keywords": [
"javascript",
"ecmascript",
"es",
"js",
"callbind",
"callbound",
"call",
"bind",
"bound",
"call-bind",
"call-bound",
"function",
"es-abstract"
],
"author": "Jordan Harband <ljharb@gmail.com>",
"funding": {
"url": "https://github.com/sponsors/ljharb"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/ljharb/call-bound/issues"
},
"homepage": "https://github.com/ljharb/call-bound#readme",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"devDependencies": {
"@arethetypeswrong/cli": "^0.17.4",
"@ljharb/eslint-config": "^21.1.1",
"@ljharb/tsconfig": "^0.3.0",
"@types/call-bind": "^1.0.5",
"@types/get-intrinsic": "^1.2.3",
"@types/tape": "^5.8.1",
"auto-changelog": "^2.5.0",
"encoding": "^0.1.13",
"es-value-fixtures": "^1.7.1",
"eslint": "=8.8.0",
"evalmd": "^0.0.19",
"for-each": "^0.3.5",
"gopd": "^1.2.0",
"has-strict-mode": "^1.1.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.1",
"nyc": "^10.3.2",
"object-inspect": "^1.13.4",
"safe-publish-latest": "^2.0.0",
"tape": "^5.9.0",
"typescript": "next"
},
"testling": {
"files": "test/index.js"
},
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
},
"publishConfig": {
"ignore": [
".github/workflows"
]
},
"engines": {
"node": ">= 0.4"
}
}

61
doubao-asr-demo/node_modules/call-bound/test/index.js generated vendored Normal file
View File

@ -0,0 +1,61 @@
'use strict';
var test = require('tape');
var callBound = require('../');
/** @template {true} T @template U @typedef {T extends U ? T : never} AssertType */
test('callBound', function (t) {
// static primitive
t.equal(callBound('Array.length'), Array.length, 'Array.length yields itself');
t.equal(callBound('%Array.length%'), Array.length, '%Array.length% yields itself');
// static non-function object
t.equal(callBound('Array.prototype'), Array.prototype, 'Array.prototype yields itself');
t.equal(callBound('%Array.prototype%'), Array.prototype, '%Array.prototype% yields itself');
t.equal(callBound('Array.constructor'), Array.constructor, 'Array.constructor yields itself');
t.equal(callBound('%Array.constructor%'), Array.constructor, '%Array.constructor% yields itself');
// static function
t.equal(callBound('Date.parse'), Date.parse, 'Date.parse yields itself');
t.equal(callBound('%Date.parse%'), Date.parse, '%Date.parse% yields itself');
// prototype primitive
t.equal(callBound('Error.prototype.message'), Error.prototype.message, 'Error.prototype.message yields itself');
t.equal(callBound('%Error.prototype.message%'), Error.prototype.message, '%Error.prototype.message% yields itself');
var x = callBound('Object.prototype.toString');
var y = callBound('%Object.prototype.toString%');
// prototype function
t.notEqual(x, Object.prototype.toString, 'Object.prototype.toString does not yield itself');
t.notEqual(y, Object.prototype.toString, '%Object.prototype.toString% does not yield itself');
t.equal(x(true), Object.prototype.toString.call(true), 'call-bound Object.prototype.toString calls into the original');
t.equal(y(true), Object.prototype.toString.call(true), 'call-bound %Object.prototype.toString% calls into the original');
t['throws'](
// @ts-expect-error
function () { callBound('does not exist'); },
SyntaxError,
'nonexistent intrinsic throws'
);
t['throws'](
// @ts-expect-error
function () { callBound('does not exist', true); },
SyntaxError,
'allowMissing arg still throws for unknown intrinsic'
);
t.test('real but absent intrinsic', { skip: typeof WeakRef !== 'undefined' }, function (st) {
st['throws'](
function () { callBound('WeakRef'); },
TypeError,
'real but absent intrinsic throws'
);
st.equal(callBound('WeakRef', true), undefined, 'allowMissing arg avoids exception');
st.end();
});
t.end();
});

10
doubao-asr-demo/node_modules/call-bound/tsconfig.json generated vendored Normal file
View File

@ -0,0 +1,10 @@
{
"extends": "@ljharb/tsconfig",
"compilerOptions": {
"target": "ESNext",
"lib": ["es2024"],
},
"exclude": [
"coverage",
],
}

View File

@ -0,0 +1,60 @@
0.5.4 / 2021-12-10
==================
* deps: safe-buffer@5.2.1
0.5.3 / 2018-12-17
==================
* Use `safe-buffer` for improved Buffer API
0.5.2 / 2016-12-08
==================
* Fix `parse` to accept any linear whitespace character
0.5.1 / 2016-01-17
==================
* perf: enable strict mode
0.5.0 / 2014-10-11
==================
* Add `parse` function
0.4.0 / 2014-09-21
==================
* Expand non-Unicode `filename` to the full ISO-8859-1 charset
0.3.0 / 2014-09-20
==================
* Add `fallback` option
* Add `type` option
0.2.0 / 2014-09-19
==================
* Reduce ambiguity of file names with hex escape in buggy browsers
0.1.2 / 2014-09-19
==================
* Fix periodic invalid Unicode filename header
0.1.1 / 2014-09-19
==================
* Fix invalid characters appearing in `filename*` parameter
0.1.0 / 2014-09-18
==================
* Make the `filename` argument optional
0.0.0 / 2014-09-18
==================
* Initial release

View File

@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2014-2017 Douglas Christopher Wilson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,142 @@
# content-disposition
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Node.js Version][node-version-image]][node-version-url]
[![Build Status][github-actions-ci-image]][github-actions-ci-url]
[![Test Coverage][coveralls-image]][coveralls-url]
Create and parse HTTP `Content-Disposition` header
## Installation
```sh
$ npm install content-disposition
```
## API
```js
var contentDisposition = require('content-disposition')
```
### contentDisposition(filename, options)
Create an attachment `Content-Disposition` header value using the given file name,
if supplied. The `filename` is optional and if no file name is desired, but you
want to specify `options`, set `filename` to `undefined`.
```js
res.setHeader('Content-Disposition', contentDisposition('∫ maths.pdf'))
```
**note** HTTP headers are of the ISO-8859-1 character set. If you are writing this
header through a means different from `setHeader` in Node.js, you'll want to specify
the `'binary'` encoding in Node.js.
#### Options
`contentDisposition` accepts these properties in the options object.
##### fallback
If the `filename` option is outside ISO-8859-1, then the file name is actually
stored in a supplemental field for clients that support Unicode file names and
a ISO-8859-1 version of the file name is automatically generated.
This specifies the ISO-8859-1 file name to override the automatic generation or
disables the generation all together, defaults to `true`.
- A string will specify the ISO-8859-1 file name to use in place of automatic
generation.
- `false` will disable including a ISO-8859-1 file name and only include the
Unicode version (unless the file name is already ISO-8859-1).
- `true` will enable automatic generation if the file name is outside ISO-8859-1.
If the `filename` option is ISO-8859-1 and this option is specified and has a
different value, then the `filename` option is encoded in the extended field
and this set as the fallback field, even though they are both ISO-8859-1.
##### type
Specifies the disposition type, defaults to `"attachment"`. This can also be
`"inline"`, or any other value (all values except inline are treated like
`attachment`, but can convey additional information if both parties agree to
it). The type is normalized to lower-case.
### contentDisposition.parse(string)
```js
var disposition = contentDisposition.parse('attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt')
```
Parse a `Content-Disposition` header string. This automatically handles extended
("Unicode") parameters by decoding them and providing them under the standard
parameter name. This will return an object with the following properties (examples
are shown for the string `'attachment; filename="EURO rates.txt"; filename*=UTF-8\'\'%e2%82%ac%20rates.txt'`):
- `type`: The disposition type (always lower case). Example: `'attachment'`
- `parameters`: An object of the parameters in the disposition (name of parameter
always lower case and extended versions replace non-extended versions). Example:
`{filename: "€ rates.txt"}`
## Examples
### Send a file for download
```js
var contentDisposition = require('content-disposition')
var destroy = require('destroy')
var fs = require('fs')
var http = require('http')
var onFinished = require('on-finished')
var filePath = '/path/to/public/plans.pdf'
http.createServer(function onRequest (req, res) {
// set headers
res.setHeader('Content-Type', 'application/pdf')
res.setHeader('Content-Disposition', contentDisposition(filePath))
// send file
var stream = fs.createReadStream(filePath)
stream.pipe(res)
onFinished(res, function () {
destroy(stream)
})
})
```
## Testing
```sh
$ npm test
```
## References
- [RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1][rfc-2616]
- [RFC 5987: Character Set and Language Encoding for Hypertext Transfer Protocol (HTTP) Header Field Parameters][rfc-5987]
- [RFC 6266: Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)][rfc-6266]
- [Test Cases for HTTP Content-Disposition header field (RFC 6266) and the Encodings defined in RFCs 2047, 2231 and 5987][tc-2231]
[rfc-2616]: https://tools.ietf.org/html/rfc2616
[rfc-5987]: https://tools.ietf.org/html/rfc5987
[rfc-6266]: https://tools.ietf.org/html/rfc6266
[tc-2231]: http://greenbytes.de/tech/tc2231/
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/content-disposition.svg
[npm-url]: https://npmjs.org/package/content-disposition
[node-version-image]: https://img.shields.io/node/v/content-disposition.svg
[node-version-url]: https://nodejs.org/en/download
[coveralls-image]: https://img.shields.io/coveralls/jshttp/content-disposition.svg
[coveralls-url]: https://coveralls.io/r/jshttp/content-disposition?branch=master
[downloads-image]: https://img.shields.io/npm/dm/content-disposition.svg
[downloads-url]: https://npmjs.org/package/content-disposition
[github-actions-ci-image]: https://img.shields.io/github/workflow/status/jshttp/content-disposition/ci/master?label=ci
[github-actions-ci-url]: https://github.com/jshttp/content-disposition?query=workflow%3Aci

View File

@ -0,0 +1,458 @@
/*!
* content-disposition
* Copyright(c) 2014-2017 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module exports.
* @public
*/
module.exports = contentDisposition
module.exports.parse = parse
/**
* Module dependencies.
* @private
*/
var basename = require('path').basename
var Buffer = require('safe-buffer').Buffer
/**
* RegExp to match non attr-char, *after* encodeURIComponent (i.e. not including "%")
* @private
*/
var ENCODE_URL_ATTR_CHAR_REGEXP = /[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g // eslint-disable-line no-control-regex
/**
* RegExp to match percent encoding escape.
* @private
*/
var HEX_ESCAPE_REGEXP = /%[0-9A-Fa-f]{2}/
var HEX_ESCAPE_REPLACE_REGEXP = /%([0-9A-Fa-f]{2})/g
/**
* RegExp to match non-latin1 characters.
* @private
*/
var NON_LATIN1_REGEXP = /[^\x20-\x7e\xa0-\xff]/g
/**
* RegExp to match quoted-pair in RFC 2616
*
* quoted-pair = "\" CHAR
* CHAR = <any US-ASCII character (octets 0 - 127)>
* @private
*/
var QESC_REGEXP = /\\([\u0000-\u007f])/g // eslint-disable-line no-control-regex
/**
* RegExp to match chars that must be quoted-pair in RFC 2616
* @private
*/
var QUOTE_REGEXP = /([\\"])/g
/**
* RegExp for various RFC 2616 grammar
*
* parameter = token "=" ( token | quoted-string )
* token = 1*<any CHAR except CTLs or separators>
* separators = "(" | ")" | "<" | ">" | "@"
* | "," | ";" | ":" | "\" | <">
* | "/" | "[" | "]" | "?" | "="
* | "{" | "}" | SP | HT
* quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
* qdtext = <any TEXT except <">>
* quoted-pair = "\" CHAR
* CHAR = <any US-ASCII character (octets 0 - 127)>
* TEXT = <any OCTET except CTLs, but including LWS>
* LWS = [CRLF] 1*( SP | HT )
* CRLF = CR LF
* CR = <US-ASCII CR, carriage return (13)>
* LF = <US-ASCII LF, linefeed (10)>
* SP = <US-ASCII SP, space (32)>
* HT = <US-ASCII HT, horizontal-tab (9)>
* CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
* OCTET = <any 8-bit sequence of data>
* @private
*/
var PARAM_REGEXP = /;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g // eslint-disable-line no-control-regex
var TEXT_REGEXP = /^[\x20-\x7e\x80-\xff]+$/
var TOKEN_REGEXP = /^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/
/**
* RegExp for various RFC 5987 grammar
*
* ext-value = charset "'" [ language ] "'" value-chars
* charset = "UTF-8" / "ISO-8859-1" / mime-charset
* mime-charset = 1*mime-charsetc
* mime-charsetc = ALPHA / DIGIT
* / "!" / "#" / "$" / "%" / "&"
* / "+" / "-" / "^" / "_" / "`"
* / "{" / "}" / "~"
* language = ( 2*3ALPHA [ extlang ] )
* / 4ALPHA
* / 5*8ALPHA
* extlang = *3( "-" 3ALPHA )
* value-chars = *( pct-encoded / attr-char )
* pct-encoded = "%" HEXDIG HEXDIG
* attr-char = ALPHA / DIGIT
* / "!" / "#" / "$" / "&" / "+" / "-" / "."
* / "^" / "_" / "`" / "|" / "~"
* @private
*/
var EXT_VALUE_REGEXP = /^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/
/**
* RegExp for various RFC 6266 grammar
*
* disposition-type = "inline" | "attachment" | disp-ext-type
* disp-ext-type = token
* disposition-parm = filename-parm | disp-ext-parm
* filename-parm = "filename" "=" value
* | "filename*" "=" ext-value
* disp-ext-parm = token "=" value
* | ext-token "=" ext-value
* ext-token = <the characters in token, followed by "*">
* @private
*/
var DISPOSITION_TYPE_REGEXP = /^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/ // eslint-disable-line no-control-regex
/**
* Create an attachment Content-Disposition header.
*
* @param {string} [filename]
* @param {object} [options]
* @param {string} [options.type=attachment]
* @param {string|boolean} [options.fallback=true]
* @return {string}
* @public
*/
function contentDisposition (filename, options) {
var opts = options || {}
// get type
var type = opts.type || 'attachment'
// get parameters
var params = createparams(filename, opts.fallback)
// format into string
return format(new ContentDisposition(type, params))
}
/**
* Create parameters object from filename and fallback.
*
* @param {string} [filename]
* @param {string|boolean} [fallback=true]
* @return {object}
* @private
*/
function createparams (filename, fallback) {
if (filename === undefined) {
return
}
var params = {}
if (typeof filename !== 'string') {
throw new TypeError('filename must be a string')
}
// fallback defaults to true
if (fallback === undefined) {
fallback = true
}
if (typeof fallback !== 'string' && typeof fallback !== 'boolean') {
throw new TypeError('fallback must be a string or boolean')
}
if (typeof fallback === 'string' && NON_LATIN1_REGEXP.test(fallback)) {
throw new TypeError('fallback must be ISO-8859-1 string')
}
// restrict to file base name
var name = basename(filename)
// determine if name is suitable for quoted string
var isQuotedString = TEXT_REGEXP.test(name)
// generate fallback name
var fallbackName = typeof fallback !== 'string'
? fallback && getlatin1(name)
: basename(fallback)
var hasFallback = typeof fallbackName === 'string' && fallbackName !== name
// set extended filename parameter
if (hasFallback || !isQuotedString || HEX_ESCAPE_REGEXP.test(name)) {
params['filename*'] = name
}
// set filename parameter
if (isQuotedString || hasFallback) {
params.filename = hasFallback
? fallbackName
: name
}
return params
}
/**
* Format object to Content-Disposition header.
*
* @param {object} obj
* @param {string} obj.type
* @param {object} [obj.parameters]
* @return {string}
* @private
*/
function format (obj) {
var parameters = obj.parameters
var type = obj.type
if (!type || typeof type !== 'string' || !TOKEN_REGEXP.test(type)) {
throw new TypeError('invalid type')
}
// start with normalized type
var string = String(type).toLowerCase()
// append parameters
if (parameters && typeof parameters === 'object') {
var param
var params = Object.keys(parameters).sort()
for (var i = 0; i < params.length; i++) {
param = params[i]
var val = param.substr(-1) === '*'
? ustring(parameters[param])
: qstring(parameters[param])
string += '; ' + param + '=' + val
}
}
return string
}
/**
* Decode a RFC 5987 field value (gracefully).
*
* @param {string} str
* @return {string}
* @private
*/
function decodefield (str) {
var match = EXT_VALUE_REGEXP.exec(str)
if (!match) {
throw new TypeError('invalid extended field value')
}
var charset = match[1].toLowerCase()
var encoded = match[2]
var value
// to binary string
var binary = encoded.replace(HEX_ESCAPE_REPLACE_REGEXP, pdecode)
switch (charset) {
case 'iso-8859-1':
value = getlatin1(binary)
break
case 'utf-8':
value = Buffer.from(binary, 'binary').toString('utf8')
break
default:
throw new TypeError('unsupported charset in extended field')
}
return value
}
/**
* Get ISO-8859-1 version of string.
*
* @param {string} val
* @return {string}
* @private
*/
function getlatin1 (val) {
// simple Unicode -> ISO-8859-1 transformation
return String(val).replace(NON_LATIN1_REGEXP, '?')
}
/**
* Parse Content-Disposition header string.
*
* @param {string} string
* @return {object}
* @public
*/
function parse (string) {
if (!string || typeof string !== 'string') {
throw new TypeError('argument string is required')
}
var match = DISPOSITION_TYPE_REGEXP.exec(string)
if (!match) {
throw new TypeError('invalid type format')
}
// normalize type
var index = match[0].length
var type = match[1].toLowerCase()
var key
var names = []
var params = {}
var value
// calculate index to start at
index = PARAM_REGEXP.lastIndex = match[0].substr(-1) === ';'
? index - 1
: index
// match parameters
while ((match = PARAM_REGEXP.exec(string))) {
if (match.index !== index) {
throw new TypeError('invalid parameter format')
}
index += match[0].length
key = match[1].toLowerCase()
value = match[2]
if (names.indexOf(key) !== -1) {
throw new TypeError('invalid duplicate parameter')
}
names.push(key)
if (key.indexOf('*') + 1 === key.length) {
// decode extended value
key = key.slice(0, -1)
value = decodefield(value)
// overwrite existing value
params[key] = value
continue
}
if (typeof params[key] === 'string') {
continue
}
if (value[0] === '"') {
// remove quotes and escapes
value = value
.substr(1, value.length - 2)
.replace(QESC_REGEXP, '$1')
}
params[key] = value
}
if (index !== -1 && index !== string.length) {
throw new TypeError('invalid parameter format')
}
return new ContentDisposition(type, params)
}
/**
* Percent decode a single character.
*
* @param {string} str
* @param {string} hex
* @return {string}
* @private
*/
function pdecode (str, hex) {
return String.fromCharCode(parseInt(hex, 16))
}
/**
* Percent encode a single character.
*
* @param {string} char
* @return {string}
* @private
*/
function pencode (char) {
return '%' + String(char)
.charCodeAt(0)
.toString(16)
.toUpperCase()
}
/**
* Quote a string for HTTP.
*
* @param {string} val
* @return {string}
* @private
*/
function qstring (val) {
var str = String(val)
return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"'
}
/**
* Encode a Unicode string for HTTP (RFC 5987).
*
* @param {string} val
* @return {string}
* @private
*/
function ustring (val) {
var str = String(val)
// percent encode as UTF-8
var encoded = encodeURIComponent(str)
.replace(ENCODE_URL_ATTR_CHAR_REGEXP, pencode)
return 'UTF-8\'\'' + encoded
}
/**
* Class for parsed Content-Disposition header for v8 optimization
*
* @public
* @param {string} type
* @param {object} parameters
* @constructor
*/
function ContentDisposition (type, parameters) {
this.type = type
this.parameters = parameters
}

View File

@ -0,0 +1,44 @@
{
"name": "content-disposition",
"description": "Create and parse Content-Disposition header",
"version": "0.5.4",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"keywords": [
"content-disposition",
"http",
"rfc6266",
"res"
],
"repository": "jshttp/content-disposition",
"dependencies": {
"safe-buffer": "5.2.1"
},
"devDependencies": {
"deep-equal": "1.0.1",
"eslint": "7.32.0",
"eslint-config-standard": "13.0.1",
"eslint-plugin-import": "2.25.3",
"eslint-plugin-markdown": "2.2.1",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "5.2.0",
"eslint-plugin-standard": "4.1.0",
"istanbul": "0.4.5",
"mocha": "9.1.3"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --bail --check-leaks test/",
"test-ci": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/"
}
}

29
doubao-asr-demo/node_modules/content-type/HISTORY.md generated vendored Normal file
View File

@ -0,0 +1,29 @@
1.0.5 / 2023-01-29
==================
* perf: skip value escaping when unnecessary
1.0.4 / 2017-09-11
==================
* perf: skip parameter parsing when no parameters
1.0.3 / 2017-09-10
==================
* perf: remove argument reassignment
1.0.2 / 2016-05-09
==================
* perf: enable strict mode
1.0.1 / 2015-02-13
==================
* Improve missing `Content-Type` header error message
1.0.0 / 2015-02-01
==================
* Initial implementation, derived from `media-typer@0.3.0`

22
doubao-asr-demo/node_modules/content-type/LICENSE generated vendored Normal file
View File

@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) 2015 Douglas Christopher Wilson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

94
doubao-asr-demo/node_modules/content-type/README.md generated vendored Normal file
View File

@ -0,0 +1,94 @@
# content-type
[![NPM Version][npm-version-image]][npm-url]
[![NPM Downloads][npm-downloads-image]][npm-url]
[![Node.js Version][node-image]][node-url]
[![Build Status][ci-image]][ci-url]
[![Coverage Status][coveralls-image]][coveralls-url]
Create and parse HTTP Content-Type header according to RFC 7231
## Installation
```sh
$ npm install content-type
```
## API
```js
var contentType = require('content-type')
```
### contentType.parse(string)
```js
var obj = contentType.parse('image/svg+xml; charset=utf-8')
```
Parse a `Content-Type` header. This will return an object with the following
properties (examples are shown for the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type (the type and subtype, always lower case).
Example: `'image/svg+xml'`
- `parameters`: An object of the parameters in the media type (name of parameter
always lower case). Example: `{charset: 'utf-8'}`
Throws a `TypeError` if the string is missing or invalid.
### contentType.parse(req)
```js
var obj = contentType.parse(req)
```
Parse the `Content-Type` header from the given `req`. Short-cut for
`contentType.parse(req.headers['content-type'])`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.parse(res)
```js
var obj = contentType.parse(res)
```
Parse the `Content-Type` header set on the given `res`. Short-cut for
`contentType.parse(res.getHeader('content-type'))`.
Throws a `TypeError` if the `Content-Type` header is missing or invalid.
### contentType.format(obj)
```js
var str = contentType.format({
type: 'image/svg+xml',
parameters: { charset: 'utf-8' }
})
```
Format an object into a `Content-Type` header. This will return a string of the
content type for the given object with the following properties (examples are
shown that produce the string `'image/svg+xml; charset=utf-8'`):
- `type`: The media type (will be lower-cased). Example: `'image/svg+xml'`
- `parameters`: An object of the parameters in the media type (name of the
parameter will be lower-cased). Example: `{charset: 'utf-8'}`
Throws a `TypeError` if the object contains an invalid type or parameter names.
## License
[MIT](LICENSE)
[ci-image]: https://badgen.net/github/checks/jshttp/content-type/master?label=ci
[ci-url]: https://github.com/jshttp/content-type/actions/workflows/ci.yml
[coveralls-image]: https://badgen.net/coveralls/c/github/jshttp/content-type/master
[coveralls-url]: https://coveralls.io/r/jshttp/content-type?branch=master
[node-image]: https://badgen.net/npm/node/content-type
[node-url]: https://nodejs.org/en/download
[npm-downloads-image]: https://badgen.net/npm/dm/content-type
[npm-url]: https://npmjs.org/package/content-type
[npm-version-image]: https://badgen.net/npm/v/content-type

225
doubao-asr-demo/node_modules/content-type/index.js generated vendored Normal file
View File

@ -0,0 +1,225 @@
/*!
* content-type
* Copyright(c) 2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* RegExp to match *( ";" parameter ) in RFC 7231 sec 3.1.1.1
*
* parameter = token "=" ( token / quoted-string )
* token = 1*tchar
* tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
* / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
* / DIGIT / ALPHA
* ; any VCHAR, except delimiters
* quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
* qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
* obs-text = %x80-FF
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
*/
var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g // eslint-disable-line no-control-regex
var TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/ // eslint-disable-line no-control-regex
var TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
/**
* RegExp to match quoted-pair in RFC 7230 sec 3.2.6
*
* quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
* obs-text = %x80-FF
*/
var QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g // eslint-disable-line no-control-regex
/**
* RegExp to match chars that must be quoted-pair in RFC 7230 sec 3.2.6
*/
var QUOTE_REGEXP = /([\\"])/g
/**
* RegExp to match type in RFC 7231 sec 3.1.1.1
*
* media-type = type "/" subtype
* type = token
* subtype = token
*/
var TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/
/**
* Module exports.
* @public
*/
exports.format = format
exports.parse = parse
/**
* Format object to media type.
*
* @param {object} obj
* @return {string}
* @public
*/
function format (obj) {
if (!obj || typeof obj !== 'object') {
throw new TypeError('argument obj is required')
}
var parameters = obj.parameters
var type = obj.type
if (!type || !TYPE_REGEXP.test(type)) {
throw new TypeError('invalid type')
}
var string = type
// append parameters
if (parameters && typeof parameters === 'object') {
var param
var params = Object.keys(parameters).sort()
for (var i = 0; i < params.length; i++) {
param = params[i]
if (!TOKEN_REGEXP.test(param)) {
throw new TypeError('invalid parameter name')
}
string += '; ' + param + '=' + qstring(parameters[param])
}
}
return string
}
/**
* Parse media type to object.
*
* @param {string|object} string
* @return {Object}
* @public
*/
function parse (string) {
if (!string) {
throw new TypeError('argument string is required')
}
// support req/res-like objects as argument
var header = typeof string === 'object'
? getcontenttype(string)
: string
if (typeof header !== 'string') {
throw new TypeError('argument string is required to be a string')
}
var index = header.indexOf(';')
var type = index !== -1
? header.slice(0, index).trim()
: header.trim()
if (!TYPE_REGEXP.test(type)) {
throw new TypeError('invalid media type')
}
var obj = new ContentType(type.toLowerCase())
// parse parameters
if (index !== -1) {
var key
var match
var value
PARAM_REGEXP.lastIndex = index
while ((match = PARAM_REGEXP.exec(header))) {
if (match.index !== index) {
throw new TypeError('invalid parameter format')
}
index += match[0].length
key = match[1].toLowerCase()
value = match[2]
if (value.charCodeAt(0) === 0x22 /* " */) {
// remove quotes
value = value.slice(1, -1)
// remove escapes
if (value.indexOf('\\') !== -1) {
value = value.replace(QESC_REGEXP, '$1')
}
}
obj.parameters[key] = value
}
if (index !== header.length) {
throw new TypeError('invalid parameter format')
}
}
return obj
}
/**
* Get content-type from req/res objects.
*
* @param {object}
* @return {Object}
* @private
*/
function getcontenttype (obj) {
var header
if (typeof obj.getHeader === 'function') {
// res-like
header = obj.getHeader('content-type')
} else if (typeof obj.headers === 'object') {
// req-like
header = obj.headers && obj.headers['content-type']
}
if (typeof header !== 'string') {
throw new TypeError('content-type header is missing from object')
}
return header
}
/**
* Quote a string if necessary.
*
* @param {string} val
* @return {string}
* @private
*/
function qstring (val) {
var str = String(val)
// no need to quote tokens
if (TOKEN_REGEXP.test(str)) {
return str
}
if (str.length > 0 && !TEXT_REGEXP.test(str)) {
throw new TypeError('invalid parameter value')
}
return '"' + str.replace(QUOTE_REGEXP, '\\$1') + '"'
}
/**
* Class to represent a content type.
* @private
*/
function ContentType (type) {
this.parameters = Object.create(null)
this.type = type
}

42
doubao-asr-demo/node_modules/content-type/package.json generated vendored Normal file
View File

@ -0,0 +1,42 @@
{
"name": "content-type",
"description": "Create and parse HTTP Content-Type header",
"version": "1.0.5",
"author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
"license": "MIT",
"keywords": [
"content-type",
"http",
"req",
"res",
"rfc7231"
],
"repository": "jshttp/content-type",
"devDependencies": {
"deep-equal": "1.0.1",
"eslint": "8.32.0",
"eslint-config-standard": "15.0.1",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "6.1.1",
"eslint-plugin-standard": "4.1.0",
"mocha": "10.2.0",
"nyc": "15.1.0"
},
"files": [
"LICENSE",
"HISTORY.md",
"README.md",
"index.js"
],
"engines": {
"node": ">= 0.6"
},
"scripts": {
"lint": "eslint .",
"test": "mocha --reporter spec --check-leaks --bail test/",
"test-ci": "nyc --reporter=lcovonly --reporter=text npm test",
"test-cov": "nyc --reporter=html --reporter=text npm test",
"version": "node scripts/version-history.js && git add HISTORY.md"
}
}

View File

@ -0,0 +1,4 @@
support
test
examples
*.sock

View File

@ -0,0 +1,38 @@
1.0.6 / 2015-02-03
==================
* use `npm test` instead of `make test` to run tests
* clearer assertion messages when checking input
1.0.5 / 2014-09-05
==================
* add license to package.json
1.0.4 / 2014-06-25
==================
* corrected avoidance of timing attacks (thanks @tenbits!)
1.0.3 / 2014-01-28
==================
* [incorrect] fix for timing attacks
1.0.2 / 2014-01-28
==================
* fix missing repository warning
* fix typo in test
1.0.1 / 2013-04-15
==================
* Revert "Changed underlying HMAC algo. to sha512."
* Revert "Fix for timing attacks on MAC verification."
0.0.1 / 2010-01-03
==================
* Initial release

View File

@ -0,0 +1,42 @@
# cookie-signature
Sign and unsign cookies.
## Example
```js
var cookie = require('cookie-signature');
var val = cookie.sign('hello', 'tobiiscool');
val.should.equal('hello.DGDUkGlIkCzPz+C0B064FNgHdEjox7ch8tOBGslZ5QI');
var val = cookie.sign('hello', 'tobiiscool');
cookie.unsign(val, 'tobiiscool').should.equal('hello');
cookie.unsign(val, 'luna').should.be.false;
```
## License
(The MIT License)
Copyright (c) 2012 LearnBoost &lt;tj@learnboost.com&gt;
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

51
doubao-asr-demo/node_modules/cookie-signature/index.js generated vendored Normal file
View File

@ -0,0 +1,51 @@
/**
* Module dependencies.
*/
var crypto = require('crypto');
/**
* Sign the given `val` with `secret`.
*
* @param {String} val
* @param {String} secret
* @return {String}
* @api private
*/
exports.sign = function(val, secret){
if ('string' != typeof val) throw new TypeError("Cookie value must be provided as a string.");
if ('string' != typeof secret) throw new TypeError("Secret string must be provided.");
return val + '.' + crypto
.createHmac('sha256', secret)
.update(val)
.digest('base64')
.replace(/\=+$/, '');
};
/**
* Unsign and decode the given `val` with `secret`,
* returning `false` if the signature is invalid.
*
* @param {String} val
* @param {String} secret
* @return {String|Boolean}
* @api private
*/
exports.unsign = function(val, secret){
if ('string' != typeof val) throw new TypeError("Signed cookie string must be provided.");
if ('string' != typeof secret) throw new TypeError("Secret string must be provided.");
var str = val.slice(0, val.lastIndexOf('.'))
, mac = exports.sign(str, secret);
return sha1(mac) == sha1(val) ? str : false;
};
/**
* Private
*/
function sha1(str){
return crypto.createHash('sha1').update(str).digest('hex');
}

Some files were not shown because too many files have changed in this diff Show More