@szjy/ai-coms 0.1.8 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +3929 -658
- package/dist/index.umd.js +2 -2
- package/dist/packages/common/audio/opfs-cache.d.ts +30 -0
- package/dist/packages/common/audio/recorder.d.ts +52 -0
- package/dist/packages/common/audio/transformers-runtime.d.ts +6 -0
- package/dist/packages/common/audio/voice-manager.d.ts +109 -0
- package/dist/packages/common/audio/whisper.worker.d.ts +7 -0
- package/dist/packages/common/audio/zh-simplified.d.ts +8 -0
- package/dist/packages/components/AiChat/src/index.vue.d.ts +30 -0
- package/dist/scripts/ai/README.md +14 -0
- package/dist/scripts/ai/whisper.worker.js +297 -0
- package/dist/style.css +2 -2
- package/package.json +19 -6
- package/dist/vite.svg +0 -1
package/dist/index.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
`)).getReader();console.log("reader from response:",t),i({error:0,reader:t})}else i({error:1,reader:null})}).catch(o=>{i({error:1,reader:null})})}):{error:1,reader:null}}let z=null;function ue(){return z||(window.markdownit?z=new window.markdownit({html:!0,linkify:!0,typographer:!0}):console.log("markdownit is not loaded"),z)}const F=(n,r)=>{const l=n.__vccOpts||n;for(const[i,o]of r)l[i]=o;return l},fe=["src","alt"],U=F({__name:"SvgIcon",props:{name:{type:String,required:!0},size:{type:[Number,String],default:16},color:{type:String,default:""},className:{type:String,default:""},basePath:{type:String,default:"/icons/"}},setup(n){const r=n,l=e.computed(()=>{if(r.name.startsWith("http://")||r.name.startsWith("https://")||r.name.startsWith("/"))return r.name;const t=r.name.endsWith(".svg")?r.name:`${r.name}.svg`;return`${r.basePath}${t}`}),i=e.computed(()=>{const t=typeof r.size=="number"?`${r.size}px`:r.size;return{width:t,height:t,display:"inline-flex",justifyContent:"center",alignItems:"center"}}),o=e.computed(()=>{const t={width:"100%",height:"100%"};return r.color&&(t.filter=`drop-shadow(0 0 0 ${r.color})`),t});return(t,a)=>(e.openBlock(),e.createElementBlock("div",{class:"svg-icon-wrapper",style:e.normalizeStyle(i.value)},[e.createElementVNode("img",{src:l.value,alt:n.name,class:e.normalizeClass(["svg-icon",n.className]),style:e.normalizeStyle(o.value)},null,14,fe)],4))}},[["__scopeId","data-v-490b11c1"]]),me=async n=>{if(navigator.clipboard&&navigator.permissions)await navigator.clipboard.writeText(n);else{const r=document.createElement("textArea");r.value=n,r.style.width=0,r.style.position="fixed",r.style.left="-999px",r.style.top="10px",r.setAttribute("readonly","readonly"),document.body.appendChild(r),r.select(),document.execCommand("copy"),document.body.removeChild(r)}},pe=["innerHTML"],he={__name:"Previewer",props:{reader:null,model:"szjy",scrollToBottomFn:null,displayText:"",messagePostRender:{type:Function,default:null}},emits:["failed","completed","updating"],setup(n,{expose:r,emit:l}){const{appContext:i}=e.getCurrentInstance(),{$message:o}=i.config.globalProperties,t=n,a=e.ref(t.displayText||""),u=e.ref(""),f=e.ref(!0),b=e.ref(!1),N=e.ref(!!t.displayText),B=l,T=e.ref(null);let C=null;const j=e.computed(()=>z?z.render(a.value):a.value),O=()=>{t.reader&&t.reader.cancel(),b.value=!0,d.value=!1,p(),N.value=!0,B("completed",a.value),f.value=!1,C&&(cancelAnimationFrame(C),C=null)},P=e.computed(()=>`${j.value}`),h=e.ref(!1),m=()=>{h.value=!0},p=()=>{h.value=!1},d=e.ref(!1),c=async()=>{if(!t.reader)return;const w=new TextDecoder("utf-8");for(f.value=!0;!b.value;)try{if(!t.reader){d.value=!0;break}const{value:s,done:k}=await t.reader.read();if(!t.reader){d.value=!0;break}if(k){d.value=!0;break}const x=q[t.model];if(!x)break;const R=x.call(q,s,w);if(R.done){d.value=!0;break}u.value+=R.content,C===null&&S()}catch(s){d.value=!0,console.log(3333,s),B("failed",s),O();break}finally{p()}},y=async()=>{t.scrollToBottomFn&&t.scrollToBottomFn()},g=(w=()=>{},s=()=>{})=>{if(u.value.length>0){const k=u.value.substring(0,10);a.value+=k,u.value=u.value.substring(10),w()}else s()},S=()=>{if(b.value&&C){cancelAnimationFrame(C),C=null,f.value=!1;return}d.value?g(()=>{C=requestAnimationFrame(S),B("updating",null)},()=>{B("completed",a.value),f.value=!1,N.value=!0,e.nextTick(()=>{if(d.value=!1,t.messagePostRender&&T.value)try{t.messagePostRender(T.value,a.value)}catch(w){console.error("messagePostRender 执行失败:",w)}}),C=null}):(g(),C=requestAnimationFrame(S)),y()};e.watch(()=>t.reader,()=>{t.reader&&c()},{immediate:!0,deep:!0}),e.onUnmounted(()=>{O()}),r({abortReader:O,initializeStart:m,initializeEnd:p}),e.computed(()=>h.value?!0:(!t.reader||!f||a.value,!1));const v=async()=>{try{const w=a.value;await me(w),o.success("复制成功")}catch(w){console.error("复制失败:",w),o.error("复制失败")}};return(w,s)=>(e.openBlock(),e.createBlock(e.Transition,{name:"fade"},{default:e.withCtx(()=>[P.value?(e.openBlock(),e.createElementBlock("div",{key:0,ref_key:"refWrapperContent",ref:T,"text-16":"",class:"w-full h-full overflow-y-auto relative","p-24px":""},[e.createElementVNode("div",{class:"markdown-wrapper",innerHTML:P.value},null,8,pe),N.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"ai-copy-btn-wrapper",onClick:v},[e.createVNode(U,{name:"/images/svg/copy.svg",color:"#666666"}),s[0]||(s[0]=e.createElementVNode("span",{class:"copy-text"},"复制",-1))])):e.createCommentVNode("",!0)],512)):e.createCommentVNode("",!0)]),_:1}))}},ye={class:"panel-header"},ge={class:"header-actions"},be={class:"header-title"},ke={class:"action-icons"},we={class:"body-content"},ve={key:0,class:"welcome-content"},Se={class:"subtitle"},xe={class:"highlight"},Ne={class:"quick-questions"},Ce=["onClick"],_e={key:1,class:"message-content user-content"},Ee={class:"panel-footer"},Te={key:0,src:ee,alt:"加载中",class:"loading-icon"},Re={class:"input-box"},Pe=["src"],Ve={__name:"ChatPanel",props:{modelValue:{type:Boolean,default:!1},token:{type:String,default:""},identifier:{type:String,default:""},baseUrl:{type:String,default:""},title:{type:String,default:"数智AI助理"},llmName:{type:String,default:"szjy"},messagePostRender:{type:Function,default:null},extraConfig:{type:Object,default:()=>({})}},emits:["update:modelValue","submit"],setup(n,{emit:r}){const{appContext:l}=e.getCurrentInstance(),{$message:i}=l.config.globalProperties,o=n,t=e.computed(()=>A.find(s=>s.modelName===o.llmName)??A.find(s=>s.modelName==="szjy")),a=r,u=e.ref(""),f=e.ref(null),b=e.ref(!1),N=e.ref([]),B=e.ref(["什么是AI助理,能做什么?","当前项目的基本情况?","当前项目的进度情况?","当前项目的参建方有哪些?","数智建管平台有哪些功能?能做什么?"]),T=e.ref([]),C=e.ref(!1),j=e.ref(null),O=()=>{e.nextTick(()=>{if(j.value){const s=j.value,k=s.scrollHeight,x=s.scrollTop,R=s.clientHeight;k-x-R<100?s.scrollTop=k:s.scrollTo({top:k})}})},P=e.ref(!1),h=e.computed(()=>P.value?"/images/ai-stop.png":"/images/ai-send.png"),m=(s,k)=>{console.log("onFailedReader",s,k),C.value=!1;const x=v();x&&x.initializeEnd(),i.error("转换失败,请重试"),P.value=!1,setTimeout(()=>{f.value&&f.value.focus()})},p=(s,k)=>{C.value=!1,P.value=!1,O(),k&&N.value[s]&&(N.value[s].displayText=k),setTimeout(()=>{f.value&&f.value.focus()})},d=s=>{P.value=!0},c=()=>{P.value=!1,a("update:modelValue",!1),b.value=!1,N.value=[]},y=e.ref(!1),g=()=>{y.value=!y.value},S=s=>{u.value=s,w()},v=()=>{for(let s=T.value.length-1;s>=0;s--)if(T.value[s])return T.value[s];return null},w=async()=>{if(console.log("stylizingLoading:",C.value),C.value){const _=v();console.log("lastPreviewer:",_),_&&(console.log("abortReader"),_.abortReader());return}if(!u.value.trim()){console.log("no input, return"),f.value.focus();return}N.value.push({type:"user",content:u.value}),P.value=!0,b.value=!0,a("submit",u.value),O();const s=u.value;u.value="";const k=N.value.length;T.value[k]&&T.value[k].initializeStart(),C.value=!0,N.value.push({type:"ai"});const{error:x,reader:R}=await de(t.value,{text:s,token:o.token,identifier:o.identifier,baseUrl:o.baseUrl,extraConfig:o.extraConfig});if(x){console.log(45455,x),m(k,x);return}R&&(N.value[k].reader=R)};return(s,k)=>{const x=e.resolveComponent("el-icon"),R=e.resolveComponent("el-input");return e.openBlock(),e.createBlock(e.Transition,{name:"slide"},{default:e.withCtx(()=>[n.modelValue?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["ai-panel",{"drawer-mode":y.value}])},[e.createElementVNode("div",ye,[e.createElementVNode("div",ge,[e.createElementVNode("div",be,e.toDisplayString(n.title),1),e.createElementVNode("div",ke,[e.createVNode(x,{class:"action-icon",onClick:g},{default:e.withCtx(()=>[e.createVNode(U,{name:"/images/svg/drawer-layout.svg",color:"#999999"})]),_:1}),e.createVNode(x,{class:"action-icon",onClick:c},{default:e.withCtx(()=>[e.createVNode(U,{name:"/images/svg/close.svg",color:"#999999"})]),_:1})])])]),e.createElementVNode("div",we,[b.value?(e.openBlock(),e.createElementBlock("div",{key:1,class:"chat-messages",ref_key:"messageContainerRef",ref:j},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(N.value,(_,L)=>(e.openBlock(),e.createElementBlock("div",{key:L,class:e.normalizeClass(["message-item",_.type==="user"?"user-message":"ai-message"])},[_.type==="ai"?(e.openBlock(),e.createBlock(he,{key:0,ref_for:!0,ref:V=>T.value[L]=V,reader:_.reader,"onUpdate:reader":V=>_.reader=V,model:o.llmName,displayText:_.displayText,scrollToBottomFn:O,messagePostRender:n.messagePostRender,onFailed:V=>m(L,V),onCompleted:V=>p(L,V),onUpdating:()=>d()},null,8,["reader","onUpdate:reader","model","displayText","messagePostRender","onFailed","onCompleted","onUpdating"])):(e.openBlock(),e.createElementBlock("div",_e,e.toDisplayString(_.content),1))],2))),128))],512)):(e.openBlock(),e.createElementBlock("div",ve,[k[2]||(k[2]=e.createElementVNode("div",{class:"title"},[e.createElementVNode("img",{src:G,alt:"AI助手",class:"panel-icon"}),e.createElementVNode("h3",{class:"title-text"},"Hi, 您好")],-1)),e.createElementVNode("div",Se,[k[1]||(k[1]=e.createTextVNode(" 我是",-1)),e.createElementVNode("span",xe,e.toDisplayString(n.title),1)]),e.createElementVNode("div",Ne,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(B.value,(_,L)=>(e.openBlock(),e.createElementBlock("div",{key:L,class:"question-item",onClick:V=>S(_)},[e.createElementVNode("span",null,e.toDisplayString(_),1),e.createVNode(x,null,{default:e.withCtx(()=>[e.createVNode(U,{name:"/images/svg/arrow-right.svg",color:"#999999"})]),_:1})],8,Ce))),128))])]))]),e.createElementVNode("div",Ee,[P.value?(e.openBlock(),e.createElementBlock("img",Te)):e.createCommentVNode("",!0),e.createElementVNode("div",Re,[e.createVNode(R,{modelValue:u.value,"onUpdate:modelValue":k[0]||(k[0]=_=>u.value=_),ref_key:"refInputTextString",ref:f,placeholder:"请输入您的问题",autofocus:"",onKeyup:e.withKeys(w,["enter"])},{append:e.withCtx(()=>[e.createElementVNode("div",{class:"send-icon-box",onClick:w},[e.createElementVNode("img",{src:h.value,alt:"发送",class:"send-icon"},null,8,Pe)])]),_:1},8,["modelValue"])])])],2)):e.createCommentVNode("",!0)]),_:1})}}};var D={exports:{}};(function(n,r){(function(l,i){n.exports=i()})(window,function(){return function(l){var i={};function o(t){if(i[t])return i[t].exports;var a=i[t]={i:t,l:!1,exports:{}};return l[t].call(a.exports,a,a.exports,o),a.l=!0,a.exports}return o.m=l,o.c=i,o.d=function(t,a,u){o.o(t,a)||Object.defineProperty(t,a,{enumerable:!0,get:u})},o.r=function(t){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},o.t=function(t,a){if(1&a&&(t=o(t)),8&a||4&a&&typeof t=="object"&&t&&t.__esModule)return t;var u=Object.create(null);if(o.r(u),Object.defineProperty(u,"default",{enumerable:!0,value:t}),2&a&&typeof t!="string")for(var f in t)o.d(u,f,(function(b){return t[b]}).bind(null,f));return u},o.n=function(t){var a=t&&t.__esModule?function(){return t.default}:function(){return t};return o.d(a,"a",a),a},o.o=function(t,a){return Object.prototype.hasOwnProperty.call(t,a)},o.p="",o(o.s=0)}([function(l,i,o){function t(h,m,p,d){p.push(h),d.push([].concat(m[h]||[]))}function a(h,m){if(!h)throw new Error("[getMaxDepsChain] dep 参数不能为空");var p=[],d=[],c=[];for(t(h,m,d,c);d.length;){var y=c.pop();if(y&&y.length){var g=y.shift();if(c.push(y),~d.indexOf(g))throw new Error("[getMaxDepsChain][loop] 存在循环依赖,请检查依赖关系; nextName: "+g+", mainStack: "+d);t(g,m,d,c)}else p.push([].concat(d)),d.pop()}return p.reduce(function(S,v){return v.length>S.length?v:S},[])}function u(h){if(!h)throw new Error("[depsParser] 入参不能为空");var m={};h.forEach(function(d){m[d.name]=d.deps||[]});var p=[];return h.forEach(function(d){var c=a(d.name,m).length-1;d.priority=c,p[c]=(p[c]||[]).concat(d)}),p}o.r(i),o.d(i,"loadScript",function(){return T}),o.d(i,"loadScripts",function(){return C}),o.d(i,"dynamicLoadScripts",function(){return j}),o.d(i,"createScriptsLoadIterator",function(){return O}),o.d(i,"loadScriptsQueue",function(){return P}),o.d(i,"getMaxDepsChain",function(){return a}),o.d(i,"depsParser",function(){return u});var f=function(){return(f=Object.assign||function(h){for(var m,p=1,d=arguments.length;p<d;p++)for(var c in m=arguments[p])Object.prototype.hasOwnProperty.call(m,c)&&(h[c]=m[c]);return h}).apply(this,arguments)},b=function(h,m,p,d){return new(p||(p=Promise))(function(c,y){function g(w){try{v(d.next(w))}catch(s){y(s)}}function S(w){try{v(d.throw(w))}catch(s){y(s)}}function v(w){var s;w.done?c(w.value):(s=w.value,s instanceof p?s:new p(function(k){k(s)})).then(g,S)}v((d=d.apply(h,[])).next())})},N=function(h,m){var p,d,c,y,g={label:0,sent:function(){if(1&c[0])throw c[1];return c[1]},trys:[],ops:[]};return y={next:S(0),throw:S(1),return:S(2)},typeof Symbol=="function"&&(y[Symbol.iterator]=function(){return this}),y;function S(v){return function(w){return function(s){if(p)throw new TypeError("Generator is already executing.");for(;g;)try{if(p=1,d&&(c=2&s[0]?d.return:s[0]?d.throw||((c=d.return)&&c.call(d),0):d.next)&&!(c=c.call(d,s[1])).done)return c;switch(d=0,c&&(s=[2&s[0],c.value]),s[0]){case 0:case 1:c=s;break;case 4:return g.label++,{value:s[1],done:!1};case 5:g.label++,d=s[1],s=[0];continue;case 7:s=g.ops.pop(),g.trys.pop();continue;default:if(c=g.trys,!((c=c.length>0&&c[c.length-1])||s[0]!==6&&s[0]!==2)){g=0;continue}if(s[0]===3&&(!c||s[1]>c[0]&&s[1]<c[3])){g.label=s[1];break}if(s[0]===6&&g.label<c[1]){g.label=c[1],c=s;break}if(c&&g.label<c[2]){g.label=c[2],g.ops.push(s);break}c[2]&&g.ops.pop(),g.trys.pop();continue}s=m.call(h,g)}catch(k){s=[6,k],d=0}finally{p=c=0}if(5&s[0])throw s[1];return{value:s[0]?s[1]:void 0,done:!0}}([v,w])}}},B=function(h){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var m,p=h[Symbol.asyncIterator];return p?p.call(h):(h=typeof __values=="function"?__values(h):h[Symbol.iterator](),m={},d("next"),d("throw"),d("return"),m[Symbol.asyncIterator]=function(){return this},m);function d(c){m[c]=h[c]&&function(y){return new Promise(function(g,S){(function(v,w,s,k){Promise.resolve(k).then(function(x){v({value:x,done:s})},w)})(g,S,(y=h[c](y)).done,y.value)})}}};function T(h,m){return m===void 0&&(m=!1),new Promise(function(p,d){var c=m?document.head:document.body,y=document.createElement("script");y.type="text/javascript",y.src=h,y.crossOrigin="anonymous",y.onreadystatechange=p,y.onload=p,y.onerror=d,c.appendChild(y)})}var C=function(h,m){return m===void 0&&(m={}),b(void 0,void 0,void 0,function(){var p,d,c,y,g;return N(this,function(S){switch(S.label){case 0:return p=m.baseUrl,d=p===void 0?"":p,c=m.lastLoadResult,y=m.inHead,g=y!==void 0&&y,[4,Promise.all(h.map(function(v){return b(void 0,void 0,void 0,function(){var w,s,k,x,R,_,L,V;return N(this,function(Y){switch(Y.label){case 0:return w=v.name,s=v.path,k=v.deps,(L={})[w]=!0,x=L,(V={})[w]=!1,R=V,window[w]?[2,x]:[3,1];case 1:return _=!0,k&&c&&[].concat(k).forEach(function(Fe){c[Fe]!==!1&&(_=!0)}),_?[4,T(s.indexOf("http")===0||s.indexOf("//:")===0?s:d+s,g).then(function(){return x}).catch(function(){return R})]:[3,3];case 2:return[2,Y.sent()];case 3:return[2,R]}})})}))];case 1:return[2,S.sent()]}})})},j=function(h,m){return m===void 0&&(m={}),function(){var p=[].concat(u(h));return{next:function(){if(p.length){var d=p.shift();return C(d,m).then(function(c){return{value:c,done:!1}})}return Promise.resolve({done:!0})}}}},O=function(h,m){var p;return m===void 0&&(m={}),(p={})[Symbol.asyncIterator]=j(h,m),p},P=function(h,m){return m===void 0&&(m={}),b(void 0,void 0,void 0,function(){var p,d,c,y,g,S;return N(this,function(v){switch(v.label){case 0:v.trys.push([0,5,6,11]),p=B(O(h,m)),v.label=1;case 1:return[4,p.next()];case 2:if((d=v.sent()).done)return[3,4];c=d.value,m.lastLoadResult=m.lastLoadResult||{},console.log("current load: ",c),c.forEach(function(w){m.lastLoadResult=f(f({},m.lastLoadResult),w)}),v.label=3;case 3:return[3,1];case 4:return[3,11];case 5:return y=v.sent(),g={error:y},[3,11];case 6:return v.trys.push([6,,9,10]),d&&!d.done&&(S=p.return)?[4,S.call(p)]:[3,8];case 7:v.sent(),v.label=8;case 8:return[3,10];case 9:if(g)throw g.error;return[7];case 10:return[7];case 11:return[2,m.lastLoadResult]}})})}}])})})(D);var Be=D.exports;const Oe={key:0,class:"ai-assistant"},Le={name:"AiChat"},je=e.defineComponent({...Le,props:{token:{type:String,default:""},identifier:{type:String,default:""},baseUrl:{type:String,default:""},title:{type:String,default:"数智AI助理"},llmName:{type:String,default:"szjy"},messagePostRender:{type:Function,default:null},extraConfig:{type:Object,default:()=>({})}},setup(n){const r=e.ref(!1),l=e.ref(!1),i=()=>{r.value=!r.value},o=()=>{l.value=!0,r.value=!1},t=f=>{console.log("用户输入:",f)},a=[{name:"markdownit",path:"markdown-it.min.js"},{name:"hljs",path:"highlight.11.11.1.min.js"}];let u={};return Be.loadScriptsQueue(a,{baseUrl:"/scripts/ai/",lastLoadResult:u,inHead:!1}).then(f=>{if(console.log("load ai deps: ",f),window.markdownit){const b=window.markdownit();console.log("markdownit: ",b),ue()}}),(f,b)=>l.value?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",Oe,[e.createVNode(Ve,{modelValue:r.value,"onUpdate:modelValue":b[0]||(b[0]=N=>r.value=N),onSubmit:t,token:n.token,identifier:n.identifier,baseUrl:n.baseUrl,title:n.title,llmName:n.llmName,messagePostRender:n.messagePostRender,extraConfig:n.extraConfig},null,8,["modelValue","token","identifier","baseUrl","title","llmName","messagePostRender","extraConfig"]),e.createElementVNode("div",{class:"ai-icon",onClick:i},[e.createElementVNode("div",{class:"close-icon",onClick:e.withModifiers(o,["stop"])},[...b[1]||(b[1]=[e.createElementVNode("svg",{viewBox:"0 0 1024 1024",width:"8",height:"8"},[e.createElementVNode("path",{d:"M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",fill:"currentColor"})],-1)])]),b[2]||(b[2]=e.createElementVNode("img",{src:Z,alt:"AI助手"},null,-1)),b[3]||(b[3]=e.createElementVNode("span",{class:"ai-icon-text"},"AI助手",-1))])]))}}),W=F(je,[["__scopeId","data-v-33f89960"]]),J=Object.freeze(Object.defineProperty({__proto__:null,SzAiChat:W},Symbol.toStringTag,{value:"Module"})),I=function(n){if(!I.installed){I.installed=!0;for(let r in J){const l=Reflect.get(J,r);n.component(l.name,l)}}},ze=(n,r)=>{const l=r?`?${new URLSearchParams(r).toString()}`:"";console.log(`点击了路由链接: ${n}${l}`)},H=n=>{const r=n.indexOf("?");if(r===-1)return{routeName:n};const l=n.substring(0,r),i=n.substring(r+1),o={};return new URLSearchParams(i).forEach((a,u)=>{o[u]=a}),{routeName:l,queryParams:Object.keys(o).length>0?o:void 0}},Ue={color:"#536fec",fontWeight:"bold",textDecoration:"underline",cursor:"pointer",padding:"0 3px"},Q=n=>{const r=/#router:([^#]+)#/g,l=[];let i=0,o;for(;(o=r.exec(n))!==null;){o.index>i&&l.push({text:n.substring(i,o.index)});const t=o[1],{routeName:a,queryParams:u}=H(t);l.push({text:a,routeName:a,queryParams:u}),i=r.lastIndex}return i<n.length&&l.push({text:n.substring(i)}),l},K=(n,r,l={},i)=>{const{onRouteClick:o=ze,linkStyle:t={}}=l,a=document.createElement("a");a.href="#",a.textContent=n;const u={...Ue,...t};return Object.assign(a.style,u),a.addEventListener("click",f=>{f.preventDefault(),o(r,i)}),a},X=n=>{const r=/#router:([^#]+)#/g,l=[],i=document.createTreeWalker(n,NodeFilter.SHOW_TEXT,null);let o=i.nextNode();for(;o;){const t=o,a=t.textContent||"";if(r.test(a)){r.lastIndex=0;const u=Q(a);u.length>0&&l.push({node:t,replacements:u})}o=i.nextNode()}return l},Ie=(n,r,l={})=>{const i=X(n);i.forEach(({node:o,replacements:t})=>{var u;const a=document.createDocumentFragment();t.forEach(({text:f,routeName:b,queryParams:N})=>{if(b){const B=K(f,b,l,N);a.appendChild(B)}else a.appendChild(document.createTextNode(f))}),(u=o.parentNode)==null||u.replaceChild(a,o)}),l!=null&&l.nodeCallback&&i.forEach(({node:o,replacements:t})=>{var a;(a=l.nodeCallback)==null||a.call(l,o,t)})},$e="0.1.8",Ae="Sz";function qe({componentPrefix:n=Ae,components:r=[]}={}){const l=[];function i(t,a,u){t.component(n+a)||t.component(n+a,u)}function o(t){l.includes(t)||(l.push(t),r.forEach(a=>{const{name:u,alias:f}=a;i(t,u,a),f&&f.forEach(b=>{i(t,b,a)})}))}return{version:$e,componentPrefix:n,install:o}}const Me={install(n){I(n)}};E.SzAiChat=W,E.create=qe,E.createRouteLink=K,E.default=Me,E.findRouteTextNodes=X,E.parseRouteMarkerContent=H,E.parseRouteMarkers=Q,E.routeLinkRender=Ie,Object.defineProperties(E,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
1
|
+
(function(b,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(b=typeof globalThis<"u"?globalThis:b||self,e(b["szjy-ai-coms"]={},b.Vue))})(this,function(b,e){"use strict";var xn=Object.defineProperty;var Tn=(b,e,q)=>e in b?xn(b,e,{enumerable:!0,configurable:!0,writable:!0,value:q}):b[e]=q;var T=(b,e,q)=>Tn(b,typeof e!="symbol"?e+"":e,q);const q="/images/ai-round.png",$e="/images/ai-sqrt.png",je="/images/bars-loading.svg";function Se(o){return o.startsWith("http://")||o.startsWith("https://")?o:`${location.protocol}//${location.host}${o}`}async function He(o,t,s,r="",a={}){const{projectId:n}=a,i=Se(r),l=new URL(`${i}/v1/chat/completions`),c=(a==null?void 0:a.authToken)||"app-oLZVFFdYyJX2QK3rdOLWsC2u";a!=null&&a.authToken||console.error("缺少 authToken!现在默认使用内网的 authToken");const m=new Request(l,{method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`},body:JSON.stringify({model:"dify",stream:!0,inputs:{token:t,projectCode:s,...n?{projectId:n}:{}},messages:[{role:"system",content:"你是一个专业的AI助手,请用中文回答问题。"},{role:"user",content:o}]})});return fetch(m)}async function qe(o,t,s,r="",a={}){const n=new URL("http://localhost:11434/api/chat"),i={};Object.keys(i).forEach(c=>{n.searchParams.append(c,i[c])});const l=new Request(n,{mode:"cors",method:"post",headers:{"Content-Type":"application/json"},body:JSON.stringify({model:"llama3",stream:!0,messages:[{role:"system",content:"全程使用中文回答问题。"},{role:"user",content:o}]})});return fetch(l)}async function We(o,t,s,r="",a={}){const n=new URL(`${location.origin}/spark/v1/chat/completions`),i={};Object.keys(i).forEach(c=>{n.searchParams.append(c,i[c])});const l=new Request(n,{method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:"generalv4.0Ultra",stream:!0,messages:[{role:"user",content:o}]})});return fetch(l)}async function Ke(o,t,s,r="",a={}){const n=new URL(`${location.origin}/siliconflow/v1/chat/completions`),i={};Object.keys(i).forEach(c=>{n.searchParams.append(c,i[c])});const l=new Request(n,{method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:"Qwen/Qwen1.5-110B-Chat",stream:!0,messages:[{role:"user",content:o}]})});return fetch(l)}async function Je(o,t,s,r="",a={}){const n=new URL(`${location.origin}/moonshot/v1/chat/completions`),i={};Object.keys(i).forEach(c=>{n.searchParams.append(c,i[c])});const l=new Request(n,{method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:"moonshot-v1-8k",stream:!0,messages:[{role:"system",content:"你是 Kimi,由 Moonshot AI 提供的人工智能助手,你更擅长中文和英文的对话。你会为用户提供安全,有帮助,准确的回答。同时,你会拒绝一切涉及恐怖主义,种族歧视,黄色暴力等问题的回答。Moonshot AI 为专有名词,不可翻译成其他语言。"},{role:"user",content:o}]})});return fetch(l)}async function Ze(o,t,s,r="",a={}){const n=new URL(`${location.origin}/dashscope/compatible-mode/v1/chat/completions`),i={};Object.keys(i).forEach(c=>{n.searchParams.append(c,i[c])});const l=new Request(n,{method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:"qwq-32b-preview",stream:!0,messages:[{role:"system",content:"全程使用中文回答问题"},{role:"user",content:o}]})});return fetch(l)}async function Qe(o,t,s,r="",a={}){const n=Se(r),i=new URL(`${n}/support/${s}/a`),l={};Object.keys(l).forEach(m=>{i.searchParams.append(m,l[m])});const c=new Request(i,{method:"post",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({content:o})});return fetch(c)}const Ge=o=>{if(o.startsWith("data:")){const t=o.substring(5).trim();if(t==="[DONE]")return{done:!0};try{return JSON.parse(t)}catch(s){console.error("JSON parsing error:",s)}}return null},Ce=[{label:"模拟数据模型",modelName:"standard",api:null},{label:"Spark 星火大模型",modelName:"spark",api:We},{label:"Ollama 3 大模型",modelName:"ollama3",api:qe},{label:"SiliconFlow 硅基流动大模型",modelName:"siliconflow",api:Ke},{label:"Kimi Moonshot 月之暗面大模型",modelName:"moonshot",api:Je},{label:"通义千问大模型",modelName:"dashscope",api:Ze},{label:"数智建管大模型",modelName:"szjy",api:Qe},{label:"Dify (OpenAI 兼容)",modelName:"dify-openai",api:He}],be={standard(o,t){let s="";return o instanceof Uint8Array?s=t.decode(o,{stream:!0}):s=o,{content:s}},spark(o){const t=Ge(o);return t.done?{done:!0}:{content:t.choices[0].delta.content||""}},siliconflow(o){return this.spark(o)},moonshot(o){return this.spark(o)},dashscope(o){return this.spark(o)},szjy(o){return this.spark(o)},"dify-openai"(o){return this.spark(o)},ollama3(o){return{content:JSON.parse(o).message.content}}},Ee=(o,t,s)=>{const r=o.split(s);return r.slice(0,-1).forEach(a=>{a.trim()!==""&&t.enqueue(a)}),r[r.length-1]},Xe=o=>{let t="";return new TransformStream({transform(s,r){if(t+=s,t.trim().startsWith("data:"))t=Ee(t,r,o);else try{JSON.parse(t),t=Ee(t,r,o)}catch{r.enqueue(s),t=""}},flush(s){t.trim()!==""&&s.enqueue(t)}})};async function Ye(o,t){const s=o.api;return s?new Promise(r=>{s(t.text,t.token,t.identifier,t.baseUrl,t.extraConfig).then(a=>{if(a.body){const n=a.body.pipeThrough(new TextDecoderStream).pipeThrough(Xe(`
|
|
2
|
+
`)).getReader();console.log("reader from response:",n),r({error:0,reader:n})}else r({error:1,reader:null})}).catch(a=>{r({error:1,reader:null})})}):{error:1,reader:null}}let W=null;function et(){return W||(window.markdownit?W=new window.markdownit({html:!0,linkify:!0,typographer:!0}):console.log("markdownit is not loaded"),W)}const ve=(o,t)=>{const s=o.__vccOpts||o;for(const[r,a]of t)s[r]=a;return s},tt=["src","alt"],Y=ve({__name:"SvgIcon",props:{name:{type:String,required:!0},size:{type:[Number,String],default:16},color:{type:String,default:""},className:{type:String,default:""},basePath:{type:String,default:"/icons/"}},setup(o){const t=o,s=e.computed(()=>{if(t.name.startsWith("http://")||t.name.startsWith("https://")||t.name.startsWith("/"))return t.name;const n=t.name.endsWith(".svg")?t.name:`${t.name}.svg`;return`${t.basePath}${n}`}),r=e.computed(()=>{const n=typeof t.size=="number"?`${t.size}px`:t.size;return{width:n,height:n,display:"inline-flex",justifyContent:"center",alignItems:"center"}}),a=e.computed(()=>{const n={width:"100%",height:"100%"};return t.color&&(n.filter=`drop-shadow(0 0 0 ${t.color})`),n});return(n,i)=>(e.openBlock(),e.createElementBlock("div",{class:"svg-icon-wrapper",style:e.normalizeStyle(r.value)},[e.createElementVNode("img",{src:s.value,alt:o.name,class:e.normalizeClass(["svg-icon",o.className]),style:e.normalizeStyle(a.value)},null,14,tt)],4))}},[["__scopeId","data-v-490b11c1"]]),nt=async o=>{if(navigator.clipboard&&navigator.permissions)await navigator.clipboard.writeText(o);else{const t=document.createElement("textArea");t.value=o,t.style.width=0,t.style.position="fixed",t.style.left="-999px",t.style.top="10px",t.setAttribute("readonly","readonly"),document.body.appendChild(t),t.select(),document.execCommand("copy"),document.body.removeChild(t)}},rt=["innerHTML"],ot={__name:"Previewer",props:{reader:null,model:"szjy",scrollToBottomFn:null,displayText:"",messagePostRender:{type:Function,default:null}},emits:["failed","completed","updating"],setup(o,{expose:t,emit:s}){const{appContext:r}=e.getCurrentInstance(),{$message:a}=r.config.globalProperties,n=o,i=e.ref(n.displayText||""),l=e.ref(""),c=e.ref(!0),m=e.ref(!1),S=e.ref(!!n.displayText),P=s,V=e.ref(null);let E=null;const F=e.computed(()=>W?W.render(i.value):i.value),x=()=>{n.reader&&n.reader.cancel(),m.value=!0,d.value=!1,y(),S.value=!0,P("completed",i.value),c.value=!1,E&&(cancelAnimationFrame(E),E=null)},A=e.computed(()=>`${F.value}`),w=e.ref(!1),g=()=>{w.value=!0},y=()=>{w.value=!1},d=e.ref(!1),u=async()=>{if(!n.reader)return;const v=new TextDecoder("utf-8");for(c.value=!0;!m.value;)try{if(!n.reader){d.value=!0;break}const{value:h,done:L}=await n.reader.read();if(!n.reader){d.value=!0;break}if(L){d.value=!0;break}const I=be[n.model];if(!I)break;const O=I.call(be,h,v);if(O.done){d.value=!0;break}l.value+=O.content,E===null&&_()}catch(h){d.value=!0,console.log(3333,h),P("failed",h),x();break}finally{y()}},C=async()=>{n.scrollToBottomFn&&n.scrollToBottomFn()},k=(v=()=>{},h=()=>{})=>{if(l.value.length>0){const L=l.value.substring(0,10);i.value+=L,l.value=l.value.substring(10),v()}else h()},_=()=>{if(m.value&&E){cancelAnimationFrame(E),E=null,c.value=!1;return}d.value?k(()=>{E=requestAnimationFrame(_),P("updating",null)},()=>{P("completed",i.value),c.value=!1,S.value=!0,e.nextTick(()=>{if(d.value=!1,n.messagePostRender&&V.value)try{n.messagePostRender(V.value,i.value)}catch(v){console.error("messagePostRender 执行失败:",v)}}),E=null}):(k(),E=requestAnimationFrame(_)),C()};e.watch(()=>n.reader,()=>{n.reader&&u()},{immediate:!0,deep:!0}),e.onUnmounted(()=>{x()}),t({abortReader:x,initializeStart:g,initializeEnd:y}),e.computed(()=>w.value?!0:(!n.reader||!c||i.value,!1));const N=async()=>{try{const v=i.value;await nt(v),a.success("复制成功")}catch(v){console.error("复制失败:",v),a.error("复制失败")}};return(v,h)=>(e.openBlock(),e.createBlock(e.Transition,{name:"fade"},{default:e.withCtx(()=>[A.value?(e.openBlock(),e.createElementBlock("div",{key:0,ref_key:"refWrapperContent",ref:V,"text-16":"",class:"w-full h-full overflow-y-auto relative","p-24px":""},[e.createElementVNode("div",{class:"markdown-wrapper",innerHTML:A.value},null,8,rt),S.value?(e.openBlock(),e.createElementBlock("div",{key:0,class:"ai-copy-btn-wrapper",onClick:N},[e.createVNode(Y,{name:"/images/svg/copy.svg",color:"#666666"}),h[0]||(h[0]=e.createElementVNode("span",{class:"copy-text"},"复制",-1))])):e.createCommentVNode("",!0)],512)):e.createCommentVNode("",!0)]),_:1}))}};class Ne{constructor(t={}){T(this,"targetSampleRate");T(this,"audioContext",null);T(this,"mediaStream",null);T(this,"sourceNode",null);T(this,"processorNode",null);T(this,"audioChunks",[]);T(this,"onVolumeChange");T(this,"onAudioChunk");T(this,"_isRecording",!1);this.targetSampleRate=t.sampleRate||16e3,this.onVolumeChange=t.onVolumeChange,this.onAudioChunk=t.onAudioChunk}get isRecording(){return this._isRecording}async start(){if(this._isRecording)return;if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia)throw new Error("当前浏览器环境不支持获取麦克风音频,请使用现代浏览器并确保在 HTTPS/localhost 环境下运行。");try{this.mediaStream=await navigator.mediaDevices.getUserMedia({audio:{channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}})}catch(r){throw r.name==="NotAllowedError"||r.name==="PermissionDeniedError"?new Error("麦克风权限被拒绝,请在浏览器地址栏允许麦克风访问权限。"):r.name==="NotFoundError"||r.name==="DevicesNotFoundError"?new Error("未检测到可用的麦克风输入设备。"):new Error(`无法启动麦克风: ${r.message||r}`)}const t=window.AudioContext||window.webkitAudioContext;this.audioContext=new t,this.audioContext.state==="suspended"&&await this.audioContext.resume(),this.audioChunks=[],this.sourceNode=this.audioContext.createMediaStreamSource(this.mediaStream);const s=4096;this.processorNode=this.audioContext.createScriptProcessor(s,1,1),this.processorNode.onaudioprocess=r=>{var i;if(!this._isRecording)return;const a=r.inputBuffer.getChannelData(0);if(this.onVolumeChange){let l=0;for(let S=0;S<a.length;S++)l+=a[S]*a[S];const c=Math.sqrt(l/a.length),m=Math.min(100,Math.round(c*100*5));this.onVolumeChange(m)}const n=this.resampleAudio(a,this.audioContext.sampleRate,this.targetSampleRate);this.audioChunks.push(n),(i=this.onAudioChunk)==null||i.call(this,n)},this.sourceNode.connect(this.processorNode),this.processorNode.connect(this.audioContext.destination),this._isRecording=!0}async stop(){if(!this._isRecording)return new Float32Array(0);this._isRecording=!1,this.cleanup();const t=this.audioChunks.reduce((a,n)=>a+n.length,0),s=new Float32Array(t);let r=0;for(const a of this.audioChunks)s.set(a,r),r+=a.length;return this.audioChunks=[],s}cancel(){this._isRecording=!1,this.audioChunks=[],this.cleanup()}cleanup(){this.processorNode&&(this.processorNode.disconnect(),this.processorNode.onaudioprocess=null,this.processorNode=null),this.sourceNode&&(this.sourceNode.disconnect(),this.sourceNode=null),this.mediaStream&&(this.mediaStream.getTracks().forEach(t=>t.stop()),this.mediaStream=null),this.audioContext&&this.audioContext.state!=="closed"&&(this.audioContext.close().catch(()=>{}),this.audioContext=null)}resampleAudio(t,s,r){return ie(t,s,r)}}function ie(o,t,s){if(t===s)return new Float32Array(o);const r=t/s,a=Math.round(o.length/r),n=new Float32Array(a);for(let i=0;i<a;i++){const l=i*r,c=Math.floor(l),m=l-c,S=o[c]??0,P=o[c+1]??S;n[i]=S+m*(P-S)}return n}async function xe(o,t=16e3){const s=await o.arrayBuffer(),r=window.AudioContext||window.webkitAudioContext,a=new r;try{const n=await a.decodeAudioData(s);let i;if(n.numberOfChannels>1){i=new Float32Array(n.length);for(let l=0;l<n.numberOfChannels;l++){const c=n.getChannelData(l);for(let m=0;m<n.length;m++)i[m]+=c[m]/n.numberOfChannels}}else i=n.getChannelData(0);return ie(i,n.sampleRate,t)}finally{a.state!=="closed"&&await a.close().catch(()=>{})}}function ee(o,t=16e3){const s=new ArrayBuffer(44+o.length*2),r=new DataView(s),a=(i,l)=>{for(let c=0;c<l.length;c++)r.setUint8(i+c,l.charCodeAt(c))};a(0,"RIFF"),r.setUint32(4,36+o.length*2,!0),a(8,"WAVE"),a(12,"fmt "),r.setUint32(16,16,!0),r.setUint16(20,1,!0),r.setUint16(22,1,!0),r.setUint32(24,t,!0),r.setUint32(28,t*2,!0),r.setUint16(32,2,!0),r.setUint16(34,16,!0),a(36,"data"),r.setUint32(40,o.length*2,!0);let n=44;for(let i=0;i<o.length;i++,n+=2){const l=Math.max(-1,Math.min(1,o[i]));r.setInt16(n,l<0?l*32768:l*32767,!0)}return new Blob([r],{type:"audio/wav"})}const at=[["網際網路","互联网"],["應用程式","应用程序"],["作業系統","操作系统"],["重新載入","重新加载"],["重新整理","刷新"],["開啟檔案","打开文件"],["電子郵件","电子邮件"],["品質管理","质量管理"],["印表機","打印机"],["伺服器","服务器"],["使用者","用户"],["記憶體","内存"],["資料庫","数据库"],["演算法","算法"],["資料夾","文件夹"],["剪貼簿","剪贴板"],["關鍵字","关键字"],["解析度","分辨率"],["執行緒","线程"],["軟體","软件"],["硬體","硬件"],["資訊","信息"],["網路","网络"],["視訊","视频"],["影片","视频"],["預設","默认"],["設定","设置"],["檔案","文件"],["資料","数据"],["程式","程序"],["螢幕","屏幕"],["硬碟","硬盘"],["滑鼠","鼠标"],["鍵盤","键盘"],["專案","项目"],["品質","质量"],["監控","监控"],["監測","监测"],["報警","报警"],["訊息","消息"],["簡訊","短信"],["物件","对象"],["元件","组件"],["模組","模块"],["函式","函数"],["迴圈","循环"],["陣列","数组"],["字串","字符串"],["畫素","像素"],["畫質","画质"],["相簿","相册"],["相冊","相册"],["登入","登录"],["登出","退出"],["註冊","注册"],["佈署","部署"],["組態","配置"],["介面","界面"],["互動","交互"],["連結","链接"],["連線","连接"],["斷線","断线"],["載入","加载"],["列印","打印"],["匯出","导出"],["匯入","导入"],["備份","备份"],["還原","还原"],["復原","恢复"],["佇列","队列"],["啟動","启动"],["開啟","打开"],["儲存","保存"],["存檔","存档"],["複製","复制"],["貼上","粘贴"],["選取","选择"],["選項","选项"],["標籤","标签"],["標題","标题"],["目錄","目录"],["路徑","路径"],["位址","地址"],["網址","网址"],["帳號","账号"],["帳戶","账户"],["密碼","密码"],["權限","权限"],["授權","授权"],["認證","认证"],["識別","识别"],["語音","语音"],["錄音","录音"],["錄製","录制"],["轉寫","转写"],["轉譯","转译"],["轉換","转换"],["繁體","繁体"],["簡體","简体"],["臺灣","台湾"],["台灣","台湾"],["裡面","里面"],["裡頭","里头"],["甚麼","什么"],["什麼","什么"],["這麼","这么"],["那麼","那么"],["怎麼","怎么"]],st=[["萬","万"],["與","与"],["醜","丑"],["專","专"],["業","业"],["叢","丛"],["東","东"],["絲","丝"],["丟","丢"],["兩","两"],["嚴","严"],["喪","丧"],["個","个"],["豐","丰"],["臨","临"],["為","为"],["麗","丽"],["舉","举"],["麼","么"],["義","义"],["烏","乌"],["樂","乐"],["喬","乔"],["習","习"],["鄉","乡"],["書","书"],["買","买"],["亂","乱"],["爭","争"],["於","于"],["虧","亏"],["雲","云"],["亙","亘"],["亞","亚"],["產","产"],["畝","亩"],["親","亲"],["褻","亵"],["億","亿"],["僅","仅"],["從","从"],["侖","仑"],["倉","仓"],["儀","仪"],["們","们"],["價","价"],["眾","众"],["優","优"],["夥","伙"],["會","会"],["傴","伛"],["傘","伞"],["偉","伟"],["傳","传"],["傷","伤"],["倀","伥"],["倫","伦"],["傖","伧"],["偽","伪"],["佇","伫"],["體","体"],["餘","余"],["傭","佣"],["僉","佥"],["俠","侠"],["侶","侣"],["僥","侥"],["偵","侦"],["側","侧"],["僑","侨"],["儈","侩"],["儕","侪"],["儂","侬"],["俁","俣"],["儔","俦"],["儼","俨"],["倆","俩"],["儷","俪"],["儉","俭"],["債","债"],["傾","倾"],["傯","偬"],["僂","偻"],["僨","偾"],["償","偿"],["儻","傥"],["儐","傧"],["儲","储"],["儺","傩"],["兒","儿"],["兌","兑"],["兗","兖"],["黨","党"],["蘭","兰"],["關","关"],["興","兴"],["茲","兹"],["養","养"],["獸","兽"],["內","内"],["岡","冈"],["冊","册"],["寫","写"],["軍","军"],["農","农"],["馮","冯"],["沖","冲"],["決","决"],["況","况"],["凍","冻"],["淨","净"],["淒","凄"],["淩","凌"],["減","减"],["湊","凑"],["凜","凛"],["幾","几"],["鳳","凤"],["鳧","凫"],["憑","凭"],["凱","凯"],["擊","击"],["鑿","凿"],["芻","刍"],["劃","划"],["劉","刘"],["則","则"],["剛","刚"],["創","创"],["刪","删"],["別","别"],["剗","刬"],["剄","刭"],["劊","刽"],["劌","刿"],["剴","剀"],["劑","剂"],["剮","剐"],["劍","剑"],["剝","剥"],["劇","剧"],["勸","劝"],["辦","办"],["務","务"],["勱","劢"],["動","动"],["勵","励"],["勁","劲"],["勞","劳"],["勢","势"],["勳","勋"],["勩","勚"],["勻","匀"],["匭","匦"],["匱","匮"],["區","区"],["醫","医"],["華","华"],["協","协"],["單","单"],["賣","卖"],["盧","卢"],["鹵","卤"],["臥","卧"],["衛","卫"],["卻","却"],["廠","厂"],["廳","厅"],["歷","历"],["厲","厉"],["壓","压"],["厭","厌"],["厙","厍"],["廁","厕"],["廂","厢"],["厴","厣"],["廈","厦"],["廚","厨"],["廄","厩"],["廝","厮"],["縣","县"],["參","参"],["雙","双"],["發","发"],["變","变"],["敘","叙"],["疊","叠"],["隻","只"],["葉","叶"],["號","号"],["歎","叹"],["嘰","叽"],["籲","吁"],["後","后"],["嚇","吓"],["呂","吕"],["嗎","吗"],["唚","吣"],["噸","吨"],["聽","听"],["啟","启"],["吳","吴"],["嘸","呒"],["囈","呓"],["嘔","呕"],["嚦","呖"],["唄","呗"],["員","员"],["咼","呙"],["嗆","呛"],["嗚","呜"],["詠","咏"],["哢","咔"],["嚨","咙"],["嚀","咛"],["噝","咝"],["吒","咤"],["響","响"],["啞","哑"],["噠","哒"],["嘵","哓"],["嗶","哔"],["噦","哕"],["嘩","哗"],["噲","哙"],["嚌","哜"],["噥","哝"],["喲","哟"],["嘜","唛"],["嗊","唝"],["嘮","唠"],["啢","唡"],["嗩","唢"],["喚","唤"],["嘖","啧"],["嗇","啬"],["囀","啭"],["齧","啮"],["囉","啰"],["嘯","啸"],["噴","喷"],["嘍","喽"],["嚳","喾"],["囁","嗫"],["噓","嘘"],["嚶","嘤"],["囑","嘱"],["嚕","噜"],["囂","嚣"],["團","团"],["園","园"],["囪","囱"],["圍","围"],["圇","囵"],["國","国"],["圖","图"],["圓","圆"],["聖","圣"],["壙","圹"],["場","场"],["壞","坏"],["塊","块"],["堅","坚"],["壇","坛"],["壢","坜"],["壩","坝"],["塢","坞"],["墳","坟"],["墜","坠"],["壟","垄"],["壘","垒"],["墾","垦"],["堊","垩"],["墊","垫"],["埡","垭"],["墶","垯"],["壋","垱"],["塏","垲"],["堖","垴"],["塒","埘"],["塤","埙"],["堝","埚"],["塹","堑"],["墮","堕"],["牆","墙"],["壯","壮"],["聲","声"],["殼","壳"],["壺","壶"],["處","处"],["備","备"],["複","复"],["夠","够"],["頭","头"],["誇","夸"],["夾","夹"],["奪","夺"],["奩","奁"],["奐","奂"],["奮","奋"],["獎","奖"],["奧","奥"],["姦","奸"],["妝","妆"],["婦","妇"],["媽","妈"],["嫵","妩"],["嫗","妪"],["媯","妫"],["姍","姗"],["薑","姜"],["婁","娄"],["婭","娅"],["嬈","娆"],["嬌","娇"],["孌","娈"],["娛","娱"],["媧","娲"],["嫻","娴"],["嬰","婴"],["嬋","婵"],["嬸","婶"],["媼","媪"],["嬡","嫒"],["嬪","嫔"],["嬙","嫱"],["嬤","嬷"],["孫","孙"],["學","学"],["孿","孪"],["寧","宁"],["寶","宝"],["實","实"],["寵","宠"],["審","审"],["憲","宪"],["宮","宫"],["寬","宽"],["賓","宾"],["寢","寝"],["對","对"],["尋","寻"],["導","导"],["壽","寿"],["將","将"],["爾","尔"],["塵","尘"],["嘗","尝"],["堯","尧"],["尷","尴"],["屍","尸"],["盡","尽"],["層","层"],["屭","屃"],["屜","屉"],["屆","届"],["屬","属"],["屢","屡"],["屨","屦"],["嶼","屿"],["歲","岁"],["豈","岂"],["嶇","岖"],["崗","岗"],["峴","岘"],["嶴","岙"],["嵐","岚"],["島","岛"],["嶺","岭"],["嶽","岳"],["巋","岿"],["嶨","峃"],["嶧","峄"],["峽","峡"],["嶢","峣"],["嶠","峤"],["崢","峥"],["巒","峦"],["嶗","崂"],["崍","崃"],["嶮","崄"],["嶄","崭"],["嶸","嵘"],["嶔","嵚"],["崳","嵛"],["嶁","嵝"],["巔","巅"],["鞏","巩"],["幣","币"],["帥","帅"],["師","师"],["幃","帏"],["帳","帐"],["簾","帘"],["幟","帜"],["帶","带"],["幀","帧"],["幫","帮"],["幬","帱"],["幘","帻"],["幗","帼"],["冪","幂"],["幹","干"],["並","并"],["廣","广"],["莊","庄"],["慶","庆"],["廬","庐"],["廡","庑"],["庫","库"],["應","应"],["廟","庙"],["龐","庞"],["廢","废"],["廎","庼"],["廩","廪"],["開","开"],["異","异"],["棄","弃"],["張","张"],["彌","弥"],["弳","弪"],["彎","弯"],["彈","弹"],["強","强"],["歸","归"],["當","当"],["錄","录"],["彥","彦"],["徹","彻"],["徑","径"],["徠","徕"],["禦","御"],["憶","忆"],["懺","忏"],["憂","忧"],["愾","忾"],["懷","怀"],["態","态"],["慫","怂"],["憮","怃"],["慪","怄"],["悵","怅"],["愴","怆"],["憐","怜"],["總","总"],["懟","怼"],["懌","怿"],["戀","恋"],["恆","恒"],["懇","恳"],["惡","恶"],["慟","恸"],["懨","恹"],["愷","恺"],["惻","恻"],["惱","恼"],["惲","恽"],["悅","悦"],["愨","悫"],["懸","悬"],["慳","悭"],["憫","悯"],["驚","惊"],["懼","惧"],["慘","惨"],["懲","惩"],["憊","惫"],["愜","惬"],["慚","惭"],["憚","惮"],["慣","惯"],["湣","悯"],["慍","愠"],["憤","愤"],["憒","愦"],["願","愿"],["懾","慑"],["懣","懑"],["懶","懒"],["懍","懔"],["戇","戆"],["戔","戋"],["戲","戏"],["戧","戗"],["戰","战"],["戩","戬"],["戶","户"],["紮","扎"],["撲","扑"],["執","执"],["擴","扩"],["捫","扪"],["掃","扫"],["揚","扬"],["擾","扰"],["撫","抚"],["拋","抛"],["摶","抟"],["摳","抠"],["掄","抡"],["搶","抢"],["護","护"],["報","报"],["擔","担"],["擬","拟"],["攏","拢"],["揀","拣"],["擁","拥"],["攔","拦"],["擰","拧"],["撥","拨"],["擇","择"],["掛","挂"],["摯","挚"],["攣","挛"],["掗","挜"],["撾","挝"],["撻","挞"],["挾","挟"],["撓","挠"],["擋","挡"],["撟","挢"],["掙","挣"],["擠","挤"],["揮","挥"],["撏","挦"],["撈","捞"],["損","损"],["撿","捡"],["換","换"],["搗","捣"],["據","据"],["撚","捻"],["擄","掳"],["摑","掴"],["擲","掷"],["撣","掸"],["摻","掺"],["摜","掼"],["摣","揸"],["擼","撸"],["擕","携"],["撳","揿"],["攙","搀"],["擱","搁"],["攬","揽"],["攤","摊"],["攪","搅"],["敵","敌"],["敗","败"],["敘","叙"],["斂","敛"],["數","数"],["齋","斋"],["斕","斓"],["鬥","斗"],["斬","斩"],["斷","断"],["無","无"],["舊","旧"],["時","时"],["曠","旷"],["暘","旸"],["曇","昙"],["晝","昼"],["曨","昽"],["顯","显"],["晉","晋"],["曬","晒"],["曉","晓"],["曄","晔"],["暈","晕"],["暉","晖"],["暫","暂"],["曖","暧"],["術","术"],["樸","朴"],["機","机"],["殺","杀"],["雜","杂"],["權","权"],["條","条"],["來","来"],["楊","杨"],["榪","杩"],["傑","杰"],["鬆","松"],["極","极"],["構","构"],["樅","枞"],["樞","枢"],["棗","枣"],["櫪","枥"],["梘","枧"],["棖","枨"],["槍","枪"],["楓","枫"],["梟","枭"],["櫃","柜"],["檸","柠"],["檉","柽"],["梔","栀"],["柵","栅"],["標","标"],["棧","栈"],["櫛","栉"],["櫳","栊"],["棟","栋"],["櫨","栌"],["櫟","栎"],["欄","栏"],["樹","树"],["棲","栖"],["樣","样"],["欒","栾"],["棬","桊"],["椏","桠"],["橈","桡"],["楨","桢"],["檔","档"],["榿","桤"],["橋","桥"],["樺","桦"],["檜","桧"],["槳","桨"],["樁","桩"],["夢","梦"],["檮","梼"],["棶","梾"],["檢","检"],["欞","棂"],["槨","椁"],["櫝","椟"],["槧","椠"],["欏","椤"],["櫓","橹"],["櫚","榈"],["櫸","榉"],["檟","槚"],["檻","槛"],["檳","槟"],["櫧","槠"],["橫","横"],["檣","樯"],["櫻","樱"],["櫫","橥"],["櫥","橱"],["櫞","橼"],["簷","檐"],["檁","檩"],["歡","欢"],["歟","欤"],["歐","欧"],["殲","歼"],["歿","殁"],["殤","殇"],["殘","残"],["殞","殒"],["殮","殓"],["殫","殚"],["殯","殡"],["毆","殴"],["毀","毁"],["轂","毂"],["畢","毕"],["斃","毙"],["氈","毡"],["毿","毵"],["氣","气"],["氫","氢"],["氬","氩"],["氳","氲"],["汙","污"],["湯","汤"],["洶","汹"],["溝","沟"],["沒","没"],["灃","沣"],["漚","沤"],["瀝","沥"],["淪","沦"],["滄","沧"],["渢","沨"],["溈","沩"],["滬","沪"],["濔","沵"],["濘","泞"],["淚","泪"],["澩","泶"],["瀧","泷"],["瀘","泸"],["濼","泺"],["瀉","泻"],["潑","泼"],["澤","泽"],["涇","泾"],["潔","洁"],["灑","洒"],["洩","泄"],["窪","洼"],["浹","浃"],["淺","浅"],["漿","浆"],["澆","浇"],["湞","浈"],["溮","浉"],["濁","浊"],["測","测"],["澮","浍"],["濟","济"],["瀏","浏"],["滻","浐"],["渾","浑"],["滸","浒"],["濃","浓"],["潯","浔"],["濜","浕"],["塗","涂"],["湧","涌"],["濤","涛"],["澇","涝"],["淶","涞"],["漣","涟"],["潿","涠"],["渦","涡"],["溳","涢"],["渙","涣"],["滌","涤"],["潤","润"],["澗","涧"],["漲","涨"],["澀","涩"],["澱","淀"],["淵","渊"],["淥","渌"],["漬","渍"],["瀆","渎"],["漸","渐"],["澠","渑"],["漁","渔"],["瀋","沈"],["滲","渗"],["溫","温"],["遊","游"],["灣","湾"],["濕","湿"],["潰","溃"],["濺","溅"],["漵","溆"],["漊","溇"],["潷","滗"],["滾","滚"],["滯","滞"],["灩","滟"],["灄","滠"],["滿","满"],["瀅","滢"],["濾","滤"],["濫","滥"],["灤","滦"],["濱","滨"],["灘","滩"],["澦","滪"],["灠","漤"],["瀠","潆"],["瀟","潇"],["瀲","潋"],["濰","潍"],["潛","潜"],["瀦","潴"],["瀾","澜"],["瀨","濑"],["瀕","濒"],["灝","灏"],["滅","灭"],["燈","灯"],["靈","灵"],["災","灾"],["燦","灿"],["煬","炀"],["爐","炉"],["燉","炖"],["煒","炜"],["熗","炝"],["點","点"],["煉","炼"],["熾","炽"],["爍","烁"],["爛","烂"],["烴","烃"],["燭","烛"],["煙","烟"],["煩","烦"],["燒","烧"],["燁","烨"],["燴","烩"],["燙","烫"],["燼","烬"],["熱","热"],["煥","焕"],["燜","焖"],["燾","焘"],["愛","爱"],["爺","爷"],["牘","牍"],["犛","牦"],["牽","牵"],["犧","牺"],["犢","犊"],["狀","状"],["獷","犷"],["獁","犸"],["猶","犹"],["狽","狈"],["獮","狝"],["獰","狞"],["獨","独"],["狹","狭"],["獅","狮"],["獪","狯"],["猙","狰"],["獄","狱"],["猻","狲"],["獫","猃"],["獵","猎"],["獼","猕"],["玀","猡"],["豬","猪"],["貓","猫"],["蝟","猬"],["獻","献"],["獺","獭"],["璣","玑"],["璵","玙"],["瑒","玚"],["瑪","玛"],["瑋","玮"],["環","环"],["現","现"],["瑲","玱"],["璽","玺"],["玨","珏"],["琺","珐"],["瓏","珑"],["璫","珰"],["琿","珲"],["璡","琎"],["璦","瑷"],["瓔","璎"],["瓚","瓒"],["甌","瓯"],["產","产"],["畫","画"],["疊","叠"],["痙","痉"],["癱","瘫"],["瘓","痪"],["皺","皱"],["盞","盏"],["鹽","盐"],["監","监"],["蓋","盖"],["盜","盗"],["盤","盘"],["瞘","眍"],["眥","眦"],["矓","眬"],["著","着"],["睜","睁"],["睞","睐"],["瞼","睑"],["瞞","瞒"],["矚","瞩"],["矯","矫"],["磯","矶"],["礬","矾"],["礦","矿"],["碭","砀"],["碼","码"],["磚","砖"],["硨","砗"],["硯","砚"],["碸","砜"],["礪","砺"],["礱","砻"],["礫","砾"],["礎","础"],["硜","硁"],["碩","硕"],["硤","硖"],["磽","硗"],["磑","硙"],["礄","硚"],["確","确"],["鹼","碱"],["礙","碍"],["磧","碛"],["磣","碜"],["禮","礼"],["禕","祎"],["禰","祢"],["禎","祯"],["禱","祷"],["穢","秽"],["積","积"],["穎","颖"],["穠","秾"],["穡","穑"],["窩","窝"],["窪","洼"],["窯","窑"],["竄","窜"],["竅","窍"],["竇","窦"],["竈","灶"],["竊","窃"],["豎","竖"],["競","竞"],["篤","笃"],["筍","笋"],["筆","笔"],["筧","笕"],["箋","笺"],["籠","笼"],["籩","笾"],["築","筑"],["篳","筚"],["篩","筛"],["簹","筜"],["箏","筝"],["籌","筹"],["簽","签"],["簡","简"],["籙","箓"],["簀","箦"],["篋","箧"],["籜","箨"],["籮","箩"],["簞","箪"],["簫","箫"],["簣","篑"],["簍","篓"],["籃","篮"],["籬","篱"],["籪","簖"],["籟","籁"],["糴","籴"],["類","类"],["秈","籼"],["糶","粜"],["糲","粝"],["粵","粤"],["糞","粪"],["糧","粮"],["糝","糁"],["緊","紧"],["縶","絷"],["糾","纠"],["紆","纡"],["紅","红"],["紂","纣"],["纖","纤"],["紇","纥"],["約","约"],["級","级"],["紈","纨"],["纊","纩"],["紀","纪"],["紉","纫"],["緯","纬"],["紜","纭"],["紘","纮"],["純","纯"],["紕","纰"],["紗","纱"],["綱","纲"],["納","纳"],["紝","纴"],["縱","纵"],["綸","纶"],["紛","纷"],["紙","纸"],["紋","纹"],["紡","纺"],["紵","纻"],["紖","纼"],["紐","纽"],["紓","纾"],["線","线"],["紺","绀"],["絏","绁"],["紱","绂"],["練","练"],["組","组"],["紳","绅"],["細","细"],["織","织"],["終","终"],["縐","绉"],["絆","绊"],["紼","绋"],["絀","绌"],["紹","绍"],["繹","绎"],["經","经"],["紿","绐"],["綁","绑"],["絨","绒"],["結","结"],["絝","绔"],["繞","绕"],["絰","绖"],["絎","绗"],["繪","绘"],["給","给"],["絢","绚"],["絳","绛"],["絡","络"],["絕","绝"],["絞","绞"],["統","统"],["綆","绠"],["綃","绡"],["絹","绢"],["繡","绣"],["綌","绤"],["綏","绥"],["絛","绦"],["繼","继"],["綈","绨"],["績","绩"],["緒","绪"],["綾","绫"],["緓","绬"],["續","续"],["綺","绮"],["緋","绯"],["綽","绰"],["緔","绱"],["緄","绲"],["繩","绳"],["維","维"],["綿","绵"],["綬","绶"],["繃","绷"],["綢","绸"],["綯","绹"],["綹","绺"],["綣","绻"],["綜","综"],["綻","绽"],["綰","绾"],["綠","绿"],["綴","缀"],["緇","缁"],["緙","缂"],["緗","缃"],["緘","缄"],["緬","缅"],["纜","缆"],["緹","缇"],["緲","缈"],["緝","缉"],["縕","缊"],["繢","缋"],["緦","缌"],["綞","缍"],["緞","缎"],["緶","缏"],["緱","缑"],["縋","缒"],["緩","缓"],["締","缔"],["縷","缕"],["編","编"],["緡","缗"],["緣","缘"],["縉","缙"],["縛","缚"],["縟","缛"],["縝","缜"],["縫","缝"],["縗","缞"],["縞","缟"],["纏","缠"],["縭","缡"],["縊","缢"],["縑","缣"],["繽","缤"],["縹","缥"],["縵","缦"],["縲","缧"],["纓","缨"],["縮","缩"],["繆","缪"],["繅","缫"],["纈","缬"],["繚","缭"],["繕","缮"],["繒","缯"],["韁","缰"],["繾","缱"],["繰","缲"],["繯","缳"],["繳","缴"],["纘","缵"],["罌","罂"],["網","网"],["羅","罗"],["罰","罚"],["罷","罢"],["羆","罴"],["羈","羁"],["羥","羟"],["羨","羡"],["翹","翘"],["耮","耢"],["耬","耧"],["聳","耸"],["恥","耻"],["聶","聂"],["聾","聋"],["職","职"],["聹","聍"],["聯","联"],["聵","聩"],["聰","聪"],["肅","肃"],["腸","肠"],["膚","肤"],["腎","肾"],["腫","肿"],["脹","胀"],["脅","胁"],["膽","胆"],["勝","胜"],["朧","胧"],["腖","胨"],["臚","胪"],["脛","胫"],["膠","胶"],["脈","脉"],["膾","脍"],["髒","脏"],["臍","脐"],["腦","脑"],["膿","脓"],["臠","脔"],["腳","脚"],["脫","脱"],["腡","脶"],["臉","脸"],["臘","腊"],["醃","腌"],["膕","腘"],["齶","腭"],["膩","腻"],["靦","腼"],["膃","腽"],["騰","腾"],["臏","膑"],["輿","舆"],["艤","舣"],["艦","舰"],["艙","舱"],["艫","舻"],["艱","艰"],["豔","艳"],["藝","艺"],["節","节"],["羋","芈"],["薌","芗"],["蕪","芜"],["蘆","芦"],["蓯","苁"],["葦","苇"],["藶","苈"],["莧","苋"],["萇","苌"],["蒼","苍"],["苧","苎"],["蘇","苏"],["蘋","苹"],["莖","茎"],["蘢","茏"],["蔦","茑"],["塋","茔"],["煢","茕"],["繭","茧"],["荊","荆"],["薦","荐"],["薘","荙"],["莢","荚"],["蕘","荛"],["蓽","荜"],["蕎","荞"],["薈","荟"],["薺","荠"],["蕩","荡"],["榮","荣"],["葷","荤"],["滎","荥"],["犖","荦"],["熒","荧"],["蕁","荨"],["藎","荩"],["蓀","荪"],["蔭","荫"],["蕒","荬"],["葒","荭"],["葤","荮"],["藥","药"],["蒞","莅"],["蓧","莜"],["萊","莱"],["蓮","莲"],["蒔","莳"],["萵","莴"],["薟","莶"],["穫","获"],["蕕","莸"],["瑩","莹"],["鶯","莺"],["蓴","莼"],["蘿","萝"],["螢","萤"],["營","营"],["縈","萦"],["蕭","萧"],["薩","萨"],["蔥","葱"],["蕆","蒇"],["蕢","蒉"],["蔣","蒋"],["蔞","蒌"],["藍","蓝"],["薊","蓟"],["蘺","蓠"],["蕷","蓣"],["鎣","蓥"],["驀","蓦"],["虆","蔂"],["薔","蔷"],["蘞","蔹"],["藺","蔺"],["藹","蔼"],["蘄","蕲"],["蘊","蕴"],["藪","薮"],["藁","藁"],["蘚","藓"],["虜","虏"],["慮","虑"],["虛","虚"],["蟲","虫"],["虯","虬"],["蟣","虮"],["雖","虽"],["蝦","虾"],["蠆","虿"],["蝕","蚀"],["蟻","蚁"],["螞","蚂"],["蠶","蚕"],["蠔","蚝"],["蜆","蚬"],["蠱","蛊"],["蠣","蛎"],["蟶","蛏"],["蠻","蛮"],["蟄","蛰"],["蛺","蛱"],["蟯","蛲"],["螄","蛳"],["蠐","蛴"],["蛻","蜕"],["蝸","蜗"],["蠟","蜡"],["蠅","蝇"],["蟈","蝈"],["蟬","蝉"],["蠍","蝎"],["蟎","螨"],["蠨","蟏"],["釁","衅"],["銜","衔"],["補","补"],["襯","衬"],["袞","衮"],["襖","袄"],["褘","袆"],["襪","袜"],["襲","袭"],["襏","袯"],["裝","装"],["襠","裆"],["褌","裈"],["褳","裢"],["襝","裣"],["褲","裤"],["襇","裥"],["褸","褛"],["襤","褴"],["見","见"],["觀","观"],["覎","觃"],["規","规"],["覓","觅"],["視","视"],["覘","觇"],["覽","览"],["覺","觉"],["覬","觊"],["覡","觋"],["覿","觌"],["覦","觎"],["覯","觏"],["覲","觐"],["覷","觑"],["觴","觞"],["觸","触"],["觶","觯"],["讋","詟"],["譽","誉"],["謄","誊"],["計","计"],["訂","订"],["訃","讣"],["認","认"],["譏","讥"],["訐","讦"],["訌","讧"],["討","讨"],["讓","让"],["訕","讪"],["訖","讫"],["訓","训"],["議","议"],["訊","讯"],["記","记"],["訒","讱"],["講","讲"],["諱","讳"],["謳","讴"],["詎","讵"],["訝","讶"],["訥","讷"],["許","许"],["訛","讹"],["論","论"],["訩","讻"],["訟","讼"],["諷","讽"],["設","设"],["訪","访"],["訣","诀"],["證","证"],["詁","诂"],["訶","诃"],["評","评"],["詛","诅"],["識","识"],["詗","诇"],["詐","诈"],["訴","诉"],["診","诊"],["詆","诋"],["謅","诌"],["詞","词"],["詘","诎"],["詔","诏"],["詖","诐"],["譯","译"],["詒","诒"],["誆","诓"],["誄","诔"],["試","试"],["詿","诖"],["詩","诗"],["詰","诘"],["詼","诙"],["誠","诚"],["誅","诛"],["詵","诜"],["話","话"],["誕","诞"],["詬","诟"],["詮","诠"],["詭","诡"],["詢","询"],["詣","诣"],["諍","诤"],["該","该"],["詳","详"],["詫","诧"],["諢","诨"],["詡","诩"],["譸","诪"],["誡","诫"],["誣","诬"],["語","语"],["誚","诮"],["誤","误"],["誥","诰"],["誘","诱"],["誨","诲"],["誑","诳"],["說","说"],["誦","诵"],["誒","诶"],["請","请"],["諸","诸"],["諏","诹"],["諾","诺"],["讀","读"],["諑","诼"],["誹","诽"],["課","课"],["諉","诿"],["諛","谀"],["誰","谁"],["諗","谂"],["調","调"],["諂","谄"],["諒","谅"],["諄","谆"],["誶","谇"],["談","谈"],["誼","谊"],["謀","谋"],["諶","谌"],["諜","谍"],["謊","谎"],["諫","谏"],["諧","谐"],["謔","谑"],["謁","谒"],["謂","谓"],["諤","谔"],["諭","谕"],["諼","谖"],["讒","谗"],["諮","谘"],["諳","谙"],["諺","谚"],["諦","谛"],["謎","谜"],["諞","谝"],["謨","谟"],["讜","谠"],["謖","谡"],["謝","谢"],["謠","谣"],["謗","谤"],["諡","谥"],["謙","谦"],["謐","谧"],["謹","谨"],["謾","谩"],["謫","谪"],["譾","谫"],["謬","谬"],["譚","谭"],["譖","谮"],["譙","谯"],["讕","谰"],["譜","谱"],["譎","谲"],["讞","谳"],["譴","谴"],["譫","谵"],["讖","谶"],["穀","谷"],["貝","贝"],["貞","贞"],["負","负"],["貟","贠"],["貢","贡"],["財","财"],["責","责"],["賢","贤"],["敗","败"],["賬","账"],["貨","货"],["質","质"],["販","贩"],["貪","贪"],["貧","贫"],["貶","贬"],["購","购"],["貯","贮"],["貫","贯"],["貳","贰"],["賤","贱"],["賁","贲"],["貰","贳"],["貼","贴"],["貴","贵"],["貺","贶"],["貸","贷"],["貿","贸"],["費","费"],["賀","贺"],["貽","贻"],["賊","贼"],["贄","贽"],["賈","贾"],["賄","贿"],["貲","赀"],["賃","赁"],["賂","赂"],["贓","赃"],["資","资"],["賅","赅"],["贐","赆"],["賕","赇"],["賑","赈"],["賚","赉"],["賒","赊"],["賦","赋"],["賭","赌"],["齎","赍"],["贖","赎"],["賞","赏"],["賜","赐"],["贔","赑"],["賙","赒"],["賡","赓"],["賠","赔"],["賧","赕"],["賴","赖"],["賵","赗"],["贅","赘"],["賻","赙"],["賺","赚"],["賽","赛"],["賾","赜"],["贊","赞"],["贇","赟"],["贈","赠"],["贍","赡"],["贏","赢"],["贛","赣"],["趙","赵"],["趕","赶"],["趨","趋"],["趲","趱"],["躉","趸"],["躍","跃"],["蹌","跄"],["蹠","跖"],["躒","跞"],["跡","迹"],["踐","践"],["躂","跶"],["蹺","跷"],["蹕","跸"],["躚","跹"],["躋","跻"],["踴","踊"],["躊","踌"],["蹤","踪"],["躓","踬"],["躑","踯"],["躡","蹑"],["蹣","蹒"],["躕","蹰"],["躥","蹿"],["躪","躏"],["躦","躜"],["軀","躯"],["車","车"],["軋","轧"],["軌","轨"],["軒","轩"],["軔","轫"],["轉","转"],["軛","轭"],["輪","轮"],["軟","软"],["轟","轰"],["軲","轱"],["軻","轲"],["轤","轳"],["軸","轴"],["軹","轵"],["軼","轶"],["軤","轷"],["軫","轸"],["轢","轹"],["軺","轺"],["輕","轻"],["軾","轼"],["載","载"],["輊","轾"],["轎","轿"],["輈","辀"],["輇","辁"],["輅","辂"],["較","较"],["輒","辄"],["輔","辅"],["輛","辆"],["輦","辇"],["輩","辈"],["輝","辉"],["輥","辊"],["輞","辋"],["輬","辌"],["輟","辍"],["輜","辎"],["輳","辏"],["輻","辐"],["輯","辑"],["轀","辒"],["輸","输"],["轡","辔"],["轅","辕"],["轄","辖"],["輾","辗"],["轆","辘"],["轍","辙"],["轔","辚"],["辭","辞"],["辯","辩"],["辮","辫"],["邊","边"],["遼","辽"],["達","达"],["遷","迁"],["過","过"],["邁","迈"],["運","运"],["還","还"],["這","这"],["進","进"],["遠","远"],["違","违"],["連","连"],["遲","迟"],["邇","迩"],["逕","迳"],["適","适"],["選","选"],["遜","逊"],["遞","递"],["邐","逦"],["邏","逻"],["遺","遗"],["遙","遥"],["鄧","邓"],["鄺","邝"],["鄔","邬"],["郵","邮"],["鄒","邹"],["鄴","邺"],["鄰","邻"],["鬱","郁"],["郟","郏"],["鄶","郐"],["鄭","郑"],["鄆","郓"],["酈","郦"],["鄖","郧"],["鄲","郸"],["醞","酝"],["醱","酦"],["醬","酱"],["釅","酽"],["釃","酾"],["釀","酿"],["釋","释"],["裡","里"],["裏","里"],["鍾","钟"],["鐘","钟"],["鐵","铁"],["銀","银"],["銅","铜"],["鋁","铝"],["鋼","钢"],["鍵","键"],["鎖","锁"],["鎮","镇"],["鏡","镜"],["長","长"],["門","门"],["閃","闪"],["閉","闭"],["問","问"],["閏","闰"],["閑","闲"],["間","间"],["閔","闵"],["閘","闸"],["鬧","闹"],["閨","闺"],["聞","闻"],["闥","闼"],["閩","闽"],["閭","闾"],["閫","阃"],["閬","阆"],["閱","阅"],["閶","阊"],["閹","阉"],["閻","阎"],["閼","阏"],["閽","阍"],["閾","阈"],["閿","阌"],["闃","阒"],["闈","闱"],["闊","阔"],["闋","阕"],["闌","阑"],["闍","阇"],["闐","阗"],["闒","阘"],["闓","闿"],["闔","阖"],["闕","阙"],["闖","闯"],["關","关"],["闞","阚"],["闡","阐"],["闢","辟"],["闥","闼"],["隊","队"],["陽","阳"],["陰","阴"],["陣","阵"],["階","阶"],["際","际"],["陸","陆"],["隴","陇"],["陳","陈"],["陘","陉"],["陝","陕"],["隉","陧"],["隕","陨"],["險","险"],["隨","随"],["隱","隐"],["隸","隶"],["雋","隽"],["難","难"],["雛","雏"],["離","离"],["難","难"],["電","电"],["霧","雾"],["霽","霁"],["靂","雳"],["靄","霭"],["靚","靓"],["靜","静"],["麵","面"],["靨","靥"],["韃","鞑"],["鞽","鞒"],["韉","鞯"],["韋","韦"],["韌","韧"],["韍","韨"],["韓","韩"],["韙","韪"],["韜","韬"],["韞","韫"],["韻","韵"],["頁","页"],["頂","顶"],["頃","顷"],["頇","顸"],["項","项"],["順","顺"],["須","须"],["頊","顼"],["頌","颂"],["頎","颀"],["頏","颃"],["預","预"],["頑","顽"],["頒","颁"],["頓","顿"],["頗","颇"],["領","领"],["頜","颌"],["頡","颉"],["頤","颐"],["頦","颏"],["頭","头"],["頮","颒"],["頰","颊"],["頲","颋"],["頴","颕"],["頷","颔"],["頸","颈"],["頹","颓"],["頻","频"],["顢","颟"],["顆","颗"],["題","题"],["額","额"],["顎","颚"],["顏","颜"],["顒","颙"],["顓","颛"],["願","愿"],["顙","颡"],["顛","颠"],["類","类"],["顥","颢"],["顧","顾"],["顫","颤"],["顬","颥"],["顯","显"],["顰","颦"],["顱","颅"],["顳","颞"],["顴","颧"],["風","风"],["颭","飐"],["颮","飑"],["颯","飒"],["颶","飓"],["颸","飔"],["颼","飕"],["颻","飖"],["飀","飗"],["飄","飘"],["飆","飙"],["飈","飚"],["飛","飞"],["饗","飨"],["饜","餍"],["饑","饥"],["饒","饶"],["饈","馐"],["饉","馑"],["饊","馓"],["饌","馔"],["饢","馕"],["馬","马"],["馭","驭"],["馮","冯"],["馱","驮"],["馳","驰"],["馴","驯"],["馹","驲"],["駁","驳"],["駐","驻"],["駑","驽"],["駒","驹"],["駔","驵"],["駕","驾"],["駘","骀"],["駙","驸"],["駛","驶"],["駝","驼"],["駟","驷"],["駡","骂"],["駢","骈"],["駭","骇"],["駮","驳"],["駱","骆"],["駸","骎"],["駿","骏"],["騁","骋"],["騂","骍"],["騅","骓"],["騌","骔"],["騍","骒"],["騎","骑"],["騏","骐"],["騖","骛"],["騙","骗"],["騤","骙"],["騧","䯄"],["騫","骞"],["騭","骘"],["騮","骝"],["騰","腾"],["騶","驺"],["騷","骚"],["騸","骟"],["騾","骡"],["驀","蓦"],["驁","骜"],["驂","骖"],["驃","骠"],["驄","骢"],["驅","驱"],["驊","骅"],["驌","骕"],["驍","骁"],["驏","骣"],["驕","骄"],["驗","验"],["驚","惊"],["驛","驿"],["驟","骤"],["驢","驴"],["驤","骧"],["驥","骥"],["驦","骦"],["驪","骊"],["驫","骉"],["骯","肮"],["髏","髅"],["髖","髋"],["髕","髌"],["鬢","鬓"],["鬥","斗"],["鬧","闹"],["鬨","哄"],["鬩","阋"],["鬮","阄"],["鬱","郁"],["魎","魉"],["魘","魇"],["魚","鱼"],["魛","鱽"],["魢","鱾"],["魨","鲀"],["魯","鲁"],["魴","鲂"],["魷","鱿"],["魺","鲄"],["鮁","鲅"],["鮃","鲆"],["鮊","鲌"],["鮋","鲉"],["鮍","鲏"],["鮎","鲇"],["鮐","鲐"],["鮑","鲍"],["鮒","鲋"],["鮓","鲊"],["鮚","鲒"],["鮜","鲘"],["鮞","鲕"],["鮦","鲖"],["鮪","鲔"],["鮫","鲛"],["鮭","鲑"],["鮮","鲜"],["鮳","鲓"],["鮶","鲪"],["鮺","鲝"],["鯀","鲧"],["鯁","鲠"],["鯇","鲩"],["鯉","鲤"],["鯊","鲨"],["鯒","鲬"],["鯔","鲻"],["鯕","鲯"],["鯖","鲭"],["鯗","鲞"],["鯛","鲷"],["鯝","鲴"],["鯡","鲱"],["鯢","鲵"],["鯤","鲲"],["鯧","鲳"],["鯨","鲸"],["鯪","鲮"],["鯫","鲰"],["鯴","鲺"],["鯽","鲫"],["鯿","鳊"],["鰁","鳈"],["鰂","鲗"],["鰃","鳂"],["鰈","鲽"],["鰉","鳇"],["鰍","鳅"],["鰏","鲾"],["鰐","鳄"],["鰒","鳆"],["鰓","鳃"],["鰜","鳒"],["鰟","鳑"],["鰠","鳋"],["鰣","鲥"],["鰥","鳏"],["鰨","鳎"],["鰩","鳐"],["鰭","鳍"],["鰮","鳁"],["鰱","鲢"],["鰲","鳌"],["鰳","鳓"],["鰵","鳘"],["鰷","鲦"],["鰹","鲣"],["鰺","鲹"],["鰻","鳗"],["鰼","鳛"],["鰾","鳔"],["鱂","鳉"],["鱅","鳙"],["鱈","鳕"],["鱉","鳖"],["鱒","鳟"],["鱔","鳝"],["鱖","鳜"],["鱗","鳞"],["鱘","鲟"],["鱝","鲼"],["鱟","鲎"],["鱠","鲙"],["鱣","鳣"],["鱤","鳡"],["鱧","鳢"],["鱨","鲿"],["鱭","鲚"],["鱯","鳠"],["鱷","鳄"],["鱸","鲈"],["鱺","鲡"],["鳥","鸟"],["鳧","凫"],["鳩","鸠"],["鳲","鸤"],["鳳","凤"],["鳴","鸣"],["鳶","鸢"],["鴆","鸩"],["鴇","鸨"],["鴉","鸦"],["鴒","鸰"],["鴕","鸵"],["鴛","鸳"],["鴝","鸲"],["鴟","鸱"],["鴣","鸪"],["鴦","鸯"],["鴨","鸭"],["鴯","鸸"],["鴰","鸹"],["鴴","鸻"],["鴻","鸿"],["鴿","鸽"],["鵂","鸺"],["鵃","鸼"],["鵐","鹀"],["鵑","鹃"],["鵒","鹆"],["鵓","鹁"],["鵜","鹈"],["鵝","鹅"],["鵠","鹄"],["鵡","鹉"],["鵪","鹌"],["鵬","鹏"],["鵯","鹎"],["鵲","鹊"],["鵷","鹓"],["鵾","鹍"],["鶇","鸫"],["鶉","鹑"],["鶊","鹒"],["鶓","鹋"],["鶖","鹙"],["鶘","鹕"],["鶚","鹗"],["鶡","鹖"],["鶥","鹛"],["鶩","鹜"],["鶬","鸧"],["鶯","莺"],["鶲","鹟"],["鶴","鹤"],["鶹","鹠"],["鶺","鹡"],["鶻","鹘"],["鶼","鹣"],["鶿","鹚"],["鷀","鹚"],["鷁","鹢"],["鷂","鹞"],["鷊","鹝"],["鷓","鹧"],["鷖","鹥"],["鷗","鸥"],["鷙","鸷"],["鷚","鹨"],["鷥","鸶"],["鷦","鹪"],["鷫","鹔"],["鷯","鹩"],["鷲","鹫"],["鷳","鹇"],["鷸","鹬"],["鷹","鹰"],["鷺","鹭"],["鷽","鸴"],["鸇","鹯"],["鸌","鹱"],["鸏","鹲"],["鸕","鸬"],["鸚","鹦"],["鸛","鹳"],["鸝","鹂"],["鸞","鸾"],["鹵","卤"],["鹹","咸"],["鹺","鹾"],["鹼","碱"],["鹽","盐"],["麗","丽"],["麥","麦"],["麩","麸"],["麵","面"],["麼","么"],["黃","黄"],["黌","黉"],["點","点"],["黨","党"],["黲","黪"],["黴","霉"],["黶","黡"],["黷","黩"],["黽","黾"],["黿","鼋"],["鼂","鼌"],["鼉","鼍"],["鼴","鼹"],["齊","齐"],["齋","斋"],["齎","赍"],["齏","齑"],["齒","齿"],["齔","龀"],["齕","龁"],["齗","龂"],["齙","龅"],["齜","龇"],["齟","龃"],["齠","龆"],["齡","龄"],["齣","出"],["齦","龈"],["齪","龊"],["齬","龉"],["齲","龋"],["齶","腭"],["齷","龌"],["龍","龙"],["龐","庞"],["龔","龚"],["龕","龛"],["龜","龟"],["係","系"],["佈","布"],["佔","占"],["併","并"],["來","来"],["例","例"],["係","系"],["臺","台"],["檯","台"],["颱","台"],["裡","里"],["纔","才"],["祇","只"],["祇","只"],["甚","甚"],["麼","么"],["衹","只"],["佈","布"],["佔","占"]];let le=null,ce=null;function it(){return le||(le=new Map(st)),le}function lt(){return ce||(ce=[...at].sort((o,t)=>t[0].length-o[0].length)),ce}function Te(o){if(!o)return o;let t=o;for(const[n,i]of lt())t.includes(n)&&(t=t.split(n).join(i));const s=it();let r=!1;const a=Array.from(t);for(let n=0;n<a.length;n++){const i=s.get(a[n]);i&&i!==a[n]&&(a[n]=i,r=!0)}return r?a.join(""):t}const te=16e3,ct=1.2,dt=2,ut=Math.round(te*2.5),ht=Math.round(te*ct),mt=Math.round(te*dt),de=Math.round(te*.4),ft=200;function Re(o,t){const s=(o||"").trim(),r=(t||"").trim();return r?s?/[A-Za-z0-9]$/.test(s)&&/[A-Za-z0-9]/.test(r.charAt(0))?`${s} ${r}`:`${s}${r}`:r:s}const ue="/scripts/ai/whisper.worker.js";function pt(){return new Worker(he(ue),{type:"module"})}function he(o){return/^https?:\/\//i.test(o)?o:typeof location<"u"?new URL(o,location.origin).href:o}function _e(o){if(!o.ok)return!1;const t=(o.headers.get("content-type")||"").toLowerCase();return!(t.includes("text/html")||t.includes("application/xhtml+xml"))}async function gt(o){try{const t=await fetch(o,{method:"HEAD"});if(_e(t))return!0}catch{}try{const t=await fetch(o,{headers:{Range:"bytes=0-64"}});if(_e(t))return!0}catch{}return!1}async function yt(o){const t=[];o&&t.push(he(o)),t.push(he(ue));const s=[...new Set(t.filter(Boolean))];for(const r of s)if(await gt(r))return console.log("[VoiceInputManager] 使用语音 Worker:",r),r;return console.warn("[VoiceInputManager] 未探测到可访问的 Worker 脚本,将回退到 Vite 打包注入地址。已尝试:",s.join(" , ")),null}class Ve{constructor(t={}){T(this,"recorder",null);T(this,"worker",null);T(this,"status","idle");T(this,"options");T(this,"isReady",!1);T(this,"initPromise",null);T(this,"currentTaskId",0);T(this,"pcmParts",[]);T(this,"pcmLength",0);T(this,"pcmSent",0);T(this,"streamBusy",!1);T(this,"streamFinalPending",!1);T(this,"streamChunkIndex",0);T(this,"committedText","");T(this,"chunkPartialText","");T(this,"streamPumpTimer",null);this.options={soundBaseUrl:"/sounds/",remoteHost:"https://hf-mirror.com",modelId:"onnx-community/whisper-base",language:"chinese",...t}}get currentStatus(){return this.status}get ready(){return this.isReady}async init(t){if(!this.isReady)return this.initPromise?this.initPromise:(t&&(this.options.soundBaseUrl=t),this.initPromise=new Promise((s,r)=>{this.setStatus("loading","正在准备语音识别引擎..."),(async()=>{var n,i;try{const l=await yt(this.options.workerUrl);this.worker=l?new Worker(l,{type:"module"}):pt(),this.worker.onmessage=c=>{this.handleWorkerMessage(c,s,r)},this.worker.onerror=c=>{var P,V;const S=`语音后台线程异常: ${c.message||c.filename||l||"未知错误"}`;this.initPromise=null,this.setStatus("error",S),(V=(P=this.options).onError)==null||V.call(P,S),r(c)},this.worker.postMessage({type:"INIT",data:{modelId:this.options.modelId,soundBaseUrl:this.options.soundBaseUrl,remoteHost:this.options.remoteHost}})}catch(l){const c=`创建语音 Worker 失败: ${l.message||l}`;this.initPromise=null,this.setStatus("error",c),(i=(n=this.options).onError)==null||i.call(n,c),r(l)}})()}),this.initPromise)}async startRecording(){var t,s,r,a;if(!navigator.mediaDevices||!navigator.mediaDevices.getUserMedia){const n=window.isSecureContext?"当前浏览器环境不支持获取麦克风音频,请使用现代浏览器。":"当前页面不是安全上下文,浏览器禁止调用麦克风。请使用 https:// 或 http://localhost / http://127.0.0.1 访问(通过局域网 IP 的 http 地址无法录音)。";throw this.setStatus("error",n),(s=(t=this.options).onError)==null||s.call(t,n),new Error(n)}this.isReady||await this.init(),this.recorder||(this.recorder=new Ne({onVolumeChange:n=>{var i,l;(l=(i=this.options).onVolumeChange)==null||l.call(i,n)},onAudioChunk:n=>{this.appendPcm(n)}}));try{this.currentTaskId++,this.resetStreamState(),await this.recorder.start(),this.startStreamPump(),this.setStatus("recording","正在录音,边说边识别...")}catch(n){throw this.setStatus("error",n.message||"启动录音失败"),(a=(r=this.options).onError)==null||a.call(r,n.message||"启动录音失败"),n}}async stopAndTranscribe(){var t,s,r,a;if(!(!this.recorder||!this.recorder.isRecording)){this.setStatus("transcribing","正在识别剩余语音..."),this.stopStreamPump();try{await this.recorder.stop();const n=this.mergePcm();if(n.length===0&&!this.committedText){this.setStatus("idle");return}try{const i=ee(n.length?n:new Float32Array(0)),l=URL.createObjectURL(i);(s=(t=this.options).onAudioRecorded)==null||s.call(t,l,i)}catch(i){console.warn("生成录音回放音频失败:",i)}this.tryDispatchStreamChunk(!0)}catch(n){this.setStatus("error",n.message||"音频处理失败"),(a=(r=this.options).onError)==null||a.call(r,n.message||"音频处理失败")}}}async transcribeAudioData(t,s){var r,a,n,i,l,c;this.isReady||await this.init(),this.setStatus("transcribing","正在流式识别音频...");try{if(s)(a=(r=this.options).onAudioRecorded)==null||a.call(r,s,ee(t));else{const m=ee(t),S=URL.createObjectURL(m);(i=(n=this.options).onAudioRecorded)==null||i.call(n,S,m)}this.currentTaskId++,this.resetStreamState(),this.appendPcm(t),this.tryDispatchStreamChunk(!0)}catch(m){this.setStatus("error",m.message||"音频处理失败"),(c=(l=this.options).onError)==null||c.call(l,m.message||"音频处理失败")}}async transcribeFile(t){var s,r;this.isReady||await this.init(),this.setStatus("loading","正在解析音频文件...");try{const a=await xe(t);if(a.length===0)throw new Error("未能从该文件中提取出有效音频");const n=URL.createObjectURL(t);await this.transcribeAudioData(a,n)}catch(a){this.setStatus("error",a.message||"音频文件解析失败"),(r=(s=this.options).onError)==null||r.call(s,a.message||"音频文件解析失败")}}cancelRecording(){this.currentTaskId++,this.stopStreamPump(),this.resetStreamState(),this.recorder&&this.recorder.cancel(),this.setStatus("idle")}cancelTranscribe(){this.currentTaskId++,this.stopStreamPump(),this.resetStreamState(),(this.status==="transcribing"||this.status==="recording")&&this.setStatus("idle")}async clearCache(){this.worker&&(this.worker.postMessage({type:"CLEAR_CACHE"}),this.isReady=!1,this.initPromise=null)}destroy(){this.currentTaskId++,this.stopStreamPump(),this.resetStreamState(),this.recorder&&(this.recorder.cancel(),this.recorder=null),this.worker&&(this.worker.terminate(),this.worker=null),this.isReady=!1,this.initPromise=null,this.setStatus("idle")}startStreamPump(){this.stopStreamPump(),this.streamPumpTimer=setInterval(()=>{this.tryDispatchStreamChunk(!1)},ft),this.tryDispatchStreamChunk(!1)}stopStreamPump(){this.streamPumpTimer!=null&&(clearInterval(this.streamPumpTimer),this.streamPumpTimer=null)}getNextChunkSize(){return this.streamFinalPending?ut:this.streamChunkIndex===0?ht:mt}resetStreamState(){this.pcmParts=[],this.pcmLength=0,this.pcmSent=0,this.streamBusy=!1,this.streamFinalPending=!1,this.streamChunkIndex=0,this.committedText="",this.chunkPartialText=""}appendPcm(t){!t||t.length===0||(this.pcmParts.push(new Float32Array(t)),this.pcmLength+=t.length)}mergePcm(){const t=new Float32Array(this.pcmLength);let s=0;for(const r of this.pcmParts)t.set(r,s),s+=r.length;return t}copyPcm(t,s){const r=new Float32Array(s);let a=0,n=0;for(const i of this.pcmParts){if(n>=s)break;if(a+i.length<=t){a+=i.length;continue}const l=Math.max(0,t-a),c=Math.min(i.length-l,s-n);r.set(i.subarray(l,l+c),n),n+=c,a+=i.length}return r}emitLiveText(){var s,r;const t=Te(Re(this.committedText,this.chunkPartialText));(r=(s=this.options).onPartial)==null||r.call(s,t)}finishStream(t){var r,a;const s=Te((t??this.committedText).trim());this.streamBusy=!1,this.streamFinalPending=!1,this.setStatus("idle"),(a=(r=this.options).onResult)==null||a.call(r,s)}tryDispatchStreamChunk(t){if(t&&(this.streamFinalPending=!0),!this.worker){this.streamFinalPending&&this.finishStream();return}if(this.streamBusy)return;const s=this.pcmLength-this.pcmSent,r=this.getNextChunkSize(),a=s>=r,n=this.streamFinalPending&&s>=de;if(!a&&!n){this.streamFinalPending&&this.finishStream();return}const i=a?r:s,l=s-i,c=this.streamFinalPending&&l<de,m=this.copyPcm(this.pcmSent,i);this.pcmSent+=i,this.streamBusy=!0,this.chunkPartialText="";const S=this.currentTaskId;this.worker.postMessage({type:"TRANSCRIBE",data:{taskId:S,audio:m,language:this.options.language,stream:!0,chunkIndex:this.streamChunkIndex++,isFinal:c}},[m.buffer])}handleWorkerMessage(t,s,r){var m,S,P,V,E;const{type:a,data:n,taskId:i,text:l,error:c}=t.data;switch(a){case"READY":this.isReady=!0,this.setStatus("ready","语音引擎就绪"),s==null||s();break;case"PROGRESS":if(n){const F=typeof n.progress=="number"?Math.round(n.progress):0;this.setStatus("downloading",`正在下载语音模型... ${F}%`),(S=(m=this.options).onProgress)==null||S.call(m,{status:n.status||"progress",progress:F,file:n.file,loaded:n.loaded,total:n.total})}break;case"TRANSCRIBING":if(i&&i!==this.currentTaskId)return;this.status!=="recording"&&this.setStatus("transcribing","正在流式转写文字...");break;case"PARTIAL":if(i&&i!==this.currentTaskId)return;this.chunkPartialText=l||"",this.emitLiveText();break;case"RESULT":if(i&&i!==this.currentTaskId)return;if(this.committedText=Re(this.committedText,l||""),this.chunkPartialText="",this.emitLiveText(),this.streamBusy=!1,(P=t.data)!=null&&P.isFinal||this.streamFinalPending&&this.pcmLength-this.pcmSent<de){this.finishStream(this.committedText);return}this.tryDispatchStreamChunk(this.streamFinalPending);break;case"CACHE_CLEARED":this.setStatus("idle","语音模型缓存已清空");break;case"ERROR":if(i&&i!==this.currentTaskId)return;this.streamBusy=!1,this.setStatus("error",c||"语音服务异常"),(E=(V=this.options).onError)==null||E.call(V,c||"语音服务异常"),r==null||r(new Error(c));break}}setStatus(t,s){var r,a;this.status=t,(a=(r=this.options).onStatusChange)==null||a.call(r,t,s)}}const wt={class:"panel-header"},kt={class:"header-actions"},St={class:"header-title"},Ct={class:"action-icons"},bt={class:"body-content"},Et={key:0,class:"welcome-content"},vt={class:"subtitle"},Nt={class:"highlight"},xt={class:"quick-questions"},Tt=["onClick"],Rt={key:1,class:"message-content user-content"},_t={class:"panel-footer"},Vt={key:0,src:je,alt:"加载中",class:"loading-icon"},Pt={key:0,class:"voice-progress-banner"},At={class:"progress-info"},Bt={class:"progress-text"},Lt={key:0,class:"progress-percent"},Mt={key:0,class:"progress-track"},Ut={key:0,class:"voice-recording-panel has-transcript"},Ft={class:"recording-main"},It={class:"recording-status"},Ot={key:0,class:"recording-time"},Dt={class:"recording-hint"},zt={key:1,class:"volume-waves"},$t={class:"recording-actions"},jt=["title"],Ht={key:0,class:"voice-playback-bar"},qt=["title"],Wt={class:"playback-play-icon"},Kt={key:0,viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor"},Jt={key:1,viewBox:"0 0 24 24",width:"14",height:"14",fill:"currentColor"},Zt={class:"playback-title"},Qt={key:0,class:"playback-time"},Gt={key:1,class:"playback-waves"},Xt={class:"input-box"},Yt={class:"input-actions-box"},en=["src"],tn={__name:"ChatPanel",props:{modelValue:{type:Boolean,default:!1},token:{type:String,default:""},identifier:{type:String,default:""},baseUrl:{type:String,default:""},title:{type:String,default:"数智AI助理"},llmName:{type:String,default:"szjy"},messagePostRender:{type:Function,default:null},extraConfig:{type:Object,default:()=>({})},soundBaseUrl:{type:String,default:"/sounds/"},workerUrl:{type:String,default:""}},emits:["update:modelValue","submit"],setup(o,{emit:t}){const{appContext:s}=e.getCurrentInstance(),{$message:r}=s.config.globalProperties,a=o;let n=null;const i=e.ref("idle"),l=e.ref(""),c=e.ref(0),m=e.ref(0),S=e.ref(0);let P=null;const V=e.ref(""),E=e.ref(!1),F=e.ref(0);let x=null;const A=e.ref(""),w=e.ref(""),g=e.computed(()=>i.value==="downloading"),y=e.computed(()=>i.value==="loading"),d=e.computed(()=>i.value==="recording"),u=e.computed(()=>i.value==="transcribing"),C=e.computed(()=>d.value?A.value?"正在边说边识别...":"正在倾听,请说话...":A.value?"正在流式转写...":"正在识别语音中..."),k=(p,f)=>{const R=(p||"").trim(),B=(f||"").trim();return B?R?/[A-Za-z0-9]$/.test(R)&&/[A-Za-z0-9]/.test(B.charAt(0))?`${R} ${B}`:`${R}${B}`:B:R},_=p=>{const f=Math.floor(p/60),R=p%60;return`${f.toString().padStart(2,"0")}:${R.toString().padStart(2,"0")}`},N=()=>(n||(n=new Ve({soundBaseUrl:a.soundBaseUrl||"/sounds/",workerUrl:a.workerUrl||void 0,onStatusChange:(p,f)=>{i.value=p,f&&(l.value=f)},onProgress:p=>{typeof p.progress=="number"&&(c.value=p.progress)},onVolumeChange:p=>{m.value=p},onAudioRecorded:p=>{V.value&&URL.revokeObjectURL(V.value),V.value=p,F.value=S.value},onPartial:p=>{A.value=p||"",M.value=k(w.value,p)},onResult:p=>{A.value=p||"",M.value=k(w.value,p),p?r.success("语音识别完成"):r.warning("未能识别出有效语音,请重试"),setTimeout(()=>{A.value="",z.value&&z.value.focus()},100)},onError:p=>{r.error(p||"语音输入服务出错"),h()}})),n),v=()=>{h(),S.value=0,P=setInterval(()=>{S.value+=1},1e3)},h=()=>{P&&(clearInterval(P),P=null)},L=async()=>{if(d.value){await I();return}E.value&&x&&(x.pause(),E.value=!1);const p=N();try{w.value=M.value,A.value="",v(),await p.startRecording()}catch(f){h(),console.error("启动录音失败:",f)}},I=async()=>{h(),n&&await n.stopAndTranscribe()},O=e.ref(null),G=()=>{O.value&&(O.value.value="",O.value.click())},oe=async p=>{var D;const f=p.target,R=(D=f==null?void 0:f.files)==null?void 0:D[0];if(!R)return;E.value&&x&&(x.pause(),E.value=!1);const B=N();try{w.value=M.value,A.value="",r.info(`正在流式识别文件: ${R.name}`),await B.transcribeFile(R)}catch(U){r.error(`文件识别失败: ${U.message||U}`)}},ae=()=>{h(),A.value="",M.value=w.value,n&&n.cancelRecording()},se=()=>{A.value="",M.value=w.value,n&&n.cancelTranscribe(),r.info("已取消本次语音识别")},fe=()=>{if(V.value){if(E.value&&x){x.pause(),E.value=!1;return}x&&(x.pause(),x=null),x=new Audio(V.value),x.onloadedmetadata=()=>{x&&!isNaN(x.duration)&&(F.value=Math.round(x.duration))},x.onended=()=>{E.value=!1},x.onerror=()=>{E.value=!1,r.error("音频试听播放失败")},x.play().then(()=>{E.value=!0}).catch(p=>{console.error("音频播放出错:",p),E.value=!1})}},Ie=()=>{x&&(x.pause(),x=null),E.value=!1,V.value&&(URL.revokeObjectURL(V.value),V.value="")};e.onBeforeUnmount(()=>{h(),Ie(),n&&(n.destroy(),n=null)});const wn=e.computed(()=>Ce.find(p=>p.modelName===a.llmName)??Ce.find(p=>p.modelName==="szjy")),Oe=t,M=e.ref(""),z=e.ref(null),pe=e.ref(!1),$=e.ref([]),kn=e.ref(["什么是AI助理,能做什么?","当前项目的基本情况?","当前项目的进度情况?","当前项目的参建方有哪些?","数智建管平台有哪些功能?能做什么?"]),J=e.ref([]),X=e.ref(!1),ge=e.ref(null),ye=()=>{e.nextTick(()=>{if(ge.value){const p=ge.value,f=p.scrollHeight,R=p.scrollTop,B=p.clientHeight;f-R-B<100?p.scrollTop=f:p.scrollTo({top:f})}})},H=e.ref(!1),Sn=e.computed(()=>H.value?"/images/ai-stop.png":"/images/ai-send.png"),De=(p,f)=>{console.log("onFailedReader",p,f),X.value=!1;const R=ze();R&&R.initializeEnd(),r.error("转换失败,请重试"),H.value=!1,setTimeout(()=>{z.value&&z.value.focus()})},Cn=(p,f)=>{X.value=!1,H.value=!1,ye(),f&&$.value[p]&&($.value[p].displayText=f),setTimeout(()=>{z.value&&z.value.focus()})},bn=p=>{H.value=!0},En=()=>{H.value=!1,Oe("update:modelValue",!1),pe.value=!1,$.value=[]},we=e.ref(!1),vn=()=>{we.value=!we.value},Nn=p=>{M.value=p,ke()},ze=()=>{for(let p=J.value.length-1;p>=0;p--)if(J.value[p])return J.value[p];return null},ke=async()=>{if(console.log("stylizingLoading:",X.value),X.value){const D=ze();console.log("lastPreviewer:",D),D&&(console.log("abortReader"),D.abortReader());return}if(!M.value.trim()){console.log("no input, return"),z.value.focus();return}$.value.push({type:"user",content:M.value}),H.value=!0,pe.value=!0,Oe("submit",M.value),ye();const p=M.value;M.value="";const f=$.value.length;J.value[f]&&J.value[f].initializeStart(),X.value=!0,$.value.push({type:"ai"});const{error:R,reader:B}=await Ye(wn.value,{text:p,token:a.token,identifier:a.identifier,baseUrl:a.baseUrl,extraConfig:a.extraConfig});if(R){console.log(45455,R),De(f,R);return}B&&($.value[f].reader=B)};return(p,f)=>{const R=e.resolveComponent("el-icon"),B=e.resolveComponent("el-button"),D=e.resolveComponent("el-input");return e.openBlock(),e.createBlock(e.Transition,{name:"slide"},{default:e.withCtx(()=>[o.modelValue?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["ai-panel",{"drawer-mode":we.value}])},[e.createElementVNode("div",wt,[e.createElementVNode("div",kt,[e.createElementVNode("div",St,e.toDisplayString(o.title),1),e.createElementVNode("div",Ct,[e.createVNode(R,{class:"action-icon",onClick:vn},{default:e.withCtx(()=>[e.createVNode(Y,{name:"/images/svg/drawer-layout.svg",color:"#999999"})]),_:1}),e.createVNode(R,{class:"action-icon",onClick:En},{default:e.withCtx(()=>[e.createVNode(Y,{name:"/images/svg/close.svg",color:"#999999"})]),_:1})])])]),e.createElementVNode("div",bt,[pe.value?(e.openBlock(),e.createElementBlock("div",{key:1,class:"chat-messages",ref_key:"messageContainerRef",ref:ge},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList($.value,(U,Z)=>(e.openBlock(),e.createElementBlock("div",{key:Z,class:e.normalizeClass(["message-item",U.type==="user"?"user-message":"ai-message"])},[U.type==="ai"?(e.openBlock(),e.createBlock(ot,{key:0,ref_for:!0,ref:j=>J.value[Z]=j,reader:U.reader,"onUpdate:reader":j=>U.reader=j,model:a.llmName,displayText:U.displayText,scrollToBottomFn:ye,messagePostRender:o.messagePostRender,onFailed:j=>De(Z,j),onCompleted:j=>Cn(Z,j),onUpdating:()=>bn()},null,8,["reader","onUpdate:reader","model","displayText","messagePostRender","onFailed","onCompleted","onUpdating"])):(e.openBlock(),e.createElementBlock("div",Rt,e.toDisplayString(U.content),1))],2))),128))],512)):(e.openBlock(),e.createElementBlock("div",Et,[f[2]||(f[2]=e.createElementVNode("div",{class:"title"},[e.createElementVNode("img",{src:$e,alt:"AI助手",class:"panel-icon"}),e.createElementVNode("h3",{class:"title-text"},"Hi, 您好")],-1)),e.createElementVNode("div",vt,[f[1]||(f[1]=e.createTextVNode(" 我是",-1)),e.createElementVNode("span",Nt,e.toDisplayString(o.title),1)]),e.createElementVNode("div",xt,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(kn.value,(U,Z)=>(e.openBlock(),e.createElementBlock("div",{key:Z,class:"question-item",onClick:j=>Nn(U)},[e.createElementVNode("span",null,e.toDisplayString(U),1),e.createVNode(R,null,{default:e.withCtx(()=>[e.createVNode(Y,{name:"/images/svg/arrow-right.svg",color:"#999999"})]),_:1})],8,Tt))),128))])]))]),e.createElementVNode("div",_t,[H.value?(e.openBlock(),e.createElementBlock("img",Vt)):e.createCommentVNode("",!0),e.createVNode(e.Transition,{name:"fade"},{default:e.withCtx(()=>[g.value||y.value?(e.openBlock(),e.createElementBlock("div",Pt,[e.createElementVNode("div",At,[f[3]||(f[3]=e.createElementVNode("span",{class:"progress-icon"},"⏳",-1)),e.createElementVNode("span",Bt,e.toDisplayString(l.value),1),c.value>0?(e.openBlock(),e.createElementBlock("span",Lt,e.toDisplayString(c.value)+"%",1)):e.createCommentVNode("",!0)]),c.value>0?(e.openBlock(),e.createElementBlock("div",Mt,[e.createElementVNode("div",{class:"progress-bar",style:e.normalizeStyle({width:c.value+"%"})},null,4)])):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0)]),_:1}),e.createVNode(e.Transition,{name:"fade"},{default:e.withCtx(()=>[d.value||u.value?(e.openBlock(),e.createElementBlock("div",Ut,[e.createElementVNode("div",Ft,[e.createElementVNode("div",It,[e.createElementVNode("span",{class:e.normalizeClass(["recording-pulse",{transcribing:u.value}])},null,2),d.value?(e.openBlock(),e.createElementBlock("span",Ot,e.toDisplayString(_(S.value)),1)):e.createCommentVNode("",!0),e.createElementVNode("span",Dt,e.toDisplayString(C.value),1),d.value?(e.openBlock(),e.createElementBlock("div",zt,[e.createElementVNode("span",{class:"wave",style:e.normalizeStyle({height:Math.max(4,Math.min(22,m.value*.3))+"px"})},null,4),e.createElementVNode("span",{class:"wave",style:e.normalizeStyle({height:Math.max(4,Math.min(30,m.value*.5))+"px"})},null,4),e.createElementVNode("span",{class:"wave",style:e.normalizeStyle({height:Math.max(4,Math.min(18,m.value*.25))+"px"})},null,4)])):e.createCommentVNode("",!0)]),e.createElementVNode("div",$t,[d.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createVNode(B,{size:"small",circle:"",onClick:ae,title:"取消录音",class:"voice-cancel-btn"},{default:e.withCtx(()=>[...f[4]||(f[4]=[e.createElementVNode("svg",{viewBox:"0 0 1024 1024",width:"12",height:"12"},[e.createElementVNode("path",{d:"M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",fill:"currentColor"})],-1)])]),_:1}),e.createVNode(B,{type:"primary",size:"small",round:"",onClick:I,class:"voice-finish-btn"},{default:e.withCtx(()=>[...f[5]||(f[5]=[e.createTextVNode(" 完成 ",-1)])]),_:1})],64)):u.value?(e.openBlock(),e.createBlock(B,{key:1,size:"small",round:"",onClick:se,class:"voice-cancel-transcribe-btn"},{default:e.withCtx(()=>[...f[6]||(f[6]=[e.createTextVNode(" 取消识别 ",-1)])]),_:1})):e.createCommentVNode("",!0)])]),e.createElementVNode("div",{class:e.normalizeClass(["live-transcript",{empty:!A.value}]),title:A.value},[A.value?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createTextVNode(e.toDisplayString(A.value),1),f[7]||(f[7]=e.createElementVNode("span",{class:"caret"},"|",-1))],64)):(e.openBlock(),e.createElementBlock(e.Fragment,{key:1},[e.createTextVNode(e.toDisplayString(d.value?"正在聆听,识别文字会实时显示在这里...":"正在识别,文字将实时显示..."),1)],64))],10,jt)])):e.createCommentVNode("",!0)]),_:1}),e.createVNode(e.Transition,{name:"fade"},{default:e.withCtx(()=>[V.value&&!d.value&&!u.value?(e.openBlock(),e.createElementBlock("div",Ht,[e.createElementVNode("div",{class:"playback-main",onClick:fe,title:E.value?"点击暂停":"点击播放录音"},[e.createElementVNode("div",Wt,[E.value?(e.openBlock(),e.createElementBlock("svg",Jt,[...f[9]||(f[9]=[e.createElementVNode("path",{d:"M6 19h4V5H6v14zm8-14v14h4V5h-4z"},null,-1)])])):(e.openBlock(),e.createElementBlock("svg",Kt,[...f[8]||(f[8]=[e.createElementVNode("path",{d:"M8 5v14l11-7z"},null,-1)])]))]),e.createElementVNode("span",Zt,e.toDisplayString(E.value?"正在播放录音...":"点击试听本次录音"),1),F.value>0?(e.openBlock(),e.createElementBlock("span",Qt,e.toDisplayString(_(F.value)),1)):e.createCommentVNode("",!0),E.value?(e.openBlock(),e.createElementBlock("div",Gt,[...f[10]||(f[10]=[e.createElementVNode("span",{class:"wave-bar"},null,-1),e.createElementVNode("span",{class:"wave-bar"},null,-1),e.createElementVNode("span",{class:"wave-bar"},null,-1),e.createElementVNode("span",{class:"wave-bar"},null,-1)])])):e.createCommentVNode("",!0)],8,qt),e.createElementVNode("div",{class:"playback-close",onClick:Ie,title:"清除试听"},[...f[11]||(f[11]=[e.createElementVNode("svg",{viewBox:"0 0 1024 1024",width:"12",height:"12"},[e.createElementVNode("path",{d:"M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",fill:"currentColor"})],-1)])])])):e.createCommentVNode("",!0)]),_:1}),e.withDirectives(e.createElementVNode("div",Xt,[e.createVNode(D,{modelValue:M.value,"onUpdate:modelValue":f[0]||(f[0]=U=>M.value=U),ref_key:"refInputTextString",ref:z,placeholder:"请输入您的问题或点击麦克风语音输入",autofocus:"",onKeyup:e.withKeys(ke,["enter"])},{append:e.withCtx(()=>[e.createElementVNode("div",Yt,[e.createElementVNode("div",{class:"voice-upload-btn",onClick:G,title:"上传音频/视频文件识别 (支持 .wav, .mp4, .mp3, .m4a)"},[...f[12]||(f[12]=[e.createElementVNode("svg",{viewBox:"0 0 24 24",width:"17",height:"17",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[e.createElementVNode("path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"}),e.createElementVNode("polyline",{points:"17 8 12 3 7 8"}),e.createElementVNode("line",{x1:"12",y1:"3",x2:"12",y2:"15"})],-1)])]),e.createElementVNode("input",{type:"file",ref_key:"refAudioFileInput",ref:O,accept:"audio/*,video/mp4,.wav,.mp4,.mp3,.m4a",style:{display:"none"},onChange:oe},null,544),e.createElementVNode("div",{class:e.normalizeClass(["voice-mic-btn",{"loading-anim":g.value||y.value}]),onClick:L,title:"语音输入"},[...f[13]||(f[13]=[e.createElementVNode("svg",{viewBox:"0 0 24 24",width:"18",height:"18",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[e.createElementVNode("path",{d:"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z",fill:"currentColor",opacity:"0.2"}),e.createElementVNode("path",{d:"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"}),e.createElementVNode("path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}),e.createElementVNode("line",{x1:"12",y1:"19",x2:"12",y2:"22"})],-1)])],2),e.createElementVNode("div",{class:"send-icon-box",onClick:ke},[e.createElementVNode("img",{src:Sn.value,alt:"发送",class:"send-icon"},null,8,en)])])]),_:1},8,["modelValue"])],512),[[e.vShow,!d.value&&!u.value]])])],2)):e.createCommentVNode("",!0)]),_:1})}}};var Pe={exports:{}};(function(o,t){(function(s,r){o.exports=r()})(window,function(){return function(s){var r={};function a(n){if(r[n])return r[n].exports;var i=r[n]={i:n,l:!1,exports:{}};return s[n].call(i.exports,i,i.exports,a),i.l=!0,i.exports}return a.m=s,a.c=r,a.d=function(n,i,l){a.o(n,i)||Object.defineProperty(n,i,{enumerable:!0,get:l})},a.r=function(n){typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},a.t=function(n,i){if(1&i&&(n=a(n)),8&i||4&i&&typeof n=="object"&&n&&n.__esModule)return n;var l=Object.create(null);if(a.r(l),Object.defineProperty(l,"default",{enumerable:!0,value:n}),2&i&&typeof n!="string")for(var c in n)a.d(l,c,(function(m){return n[m]}).bind(null,c));return l},a.n=function(n){var i=n&&n.__esModule?function(){return n.default}:function(){return n};return a.d(i,"a",i),i},a.o=function(n,i){return Object.prototype.hasOwnProperty.call(n,i)},a.p="",a(a.s=0)}([function(s,r,a){function n(w,g,y,d){y.push(w),d.push([].concat(g[w]||[]))}function i(w,g){if(!w)throw new Error("[getMaxDepsChain] dep 参数不能为空");var y=[],d=[],u=[];for(n(w,g,d,u);d.length;){var C=u.pop();if(C&&C.length){var k=C.shift();if(u.push(C),~d.indexOf(k))throw new Error("[getMaxDepsChain][loop] 存在循环依赖,请检查依赖关系; nextName: "+k+", mainStack: "+d);n(k,g,d,u)}else y.push([].concat(d)),d.pop()}return y.reduce(function(_,N){return N.length>_.length?N:_},[])}function l(w){if(!w)throw new Error("[depsParser] 入参不能为空");var g={};w.forEach(function(d){g[d.name]=d.deps||[]});var y=[];return w.forEach(function(d){var u=i(d.name,g).length-1;d.priority=u,y[u]=(y[u]||[]).concat(d)}),y}a.r(r),a.d(r,"loadScript",function(){return V}),a.d(r,"loadScripts",function(){return E}),a.d(r,"dynamicLoadScripts",function(){return F}),a.d(r,"createScriptsLoadIterator",function(){return x}),a.d(r,"loadScriptsQueue",function(){return A}),a.d(r,"getMaxDepsChain",function(){return i}),a.d(r,"depsParser",function(){return l});var c=function(){return(c=Object.assign||function(w){for(var g,y=1,d=arguments.length;y<d;y++)for(var u in g=arguments[y])Object.prototype.hasOwnProperty.call(g,u)&&(w[u]=g[u]);return w}).apply(this,arguments)},m=function(w,g,y,d){return new(y||(y=Promise))(function(u,C){function k(v){try{N(d.next(v))}catch(h){C(h)}}function _(v){try{N(d.throw(v))}catch(h){C(h)}}function N(v){var h;v.done?u(v.value):(h=v.value,h instanceof y?h:new y(function(L){L(h)})).then(k,_)}N((d=d.apply(w,[])).next())})},S=function(w,g){var y,d,u,C,k={label:0,sent:function(){if(1&u[0])throw u[1];return u[1]},trys:[],ops:[]};return C={next:_(0),throw:_(1),return:_(2)},typeof Symbol=="function"&&(C[Symbol.iterator]=function(){return this}),C;function _(N){return function(v){return function(h){if(y)throw new TypeError("Generator is already executing.");for(;k;)try{if(y=1,d&&(u=2&h[0]?d.return:h[0]?d.throw||((u=d.return)&&u.call(d),0):d.next)&&!(u=u.call(d,h[1])).done)return u;switch(d=0,u&&(h=[2&h[0],u.value]),h[0]){case 0:case 1:u=h;break;case 4:return k.label++,{value:h[1],done:!1};case 5:k.label++,d=h[1],h=[0];continue;case 7:h=k.ops.pop(),k.trys.pop();continue;default:if(u=k.trys,!((u=u.length>0&&u[u.length-1])||h[0]!==6&&h[0]!==2)){k=0;continue}if(h[0]===3&&(!u||h[1]>u[0]&&h[1]<u[3])){k.label=h[1];break}if(h[0]===6&&k.label<u[1]){k.label=u[1],u=h;break}if(u&&k.label<u[2]){k.label=u[2],k.ops.push(h);break}u[2]&&k.ops.pop(),k.trys.pop();continue}h=g.call(w,k)}catch(L){h=[6,L],d=0}finally{y=u=0}if(5&h[0])throw h[1];return{value:h[0]?h[1]:void 0,done:!0}}([N,v])}}},P=function(w){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var g,y=w[Symbol.asyncIterator];return y?y.call(w):(w=typeof __values=="function"?__values(w):w[Symbol.iterator](),g={},d("next"),d("throw"),d("return"),g[Symbol.asyncIterator]=function(){return this},g);function d(u){g[u]=w[u]&&function(C){return new Promise(function(k,_){(function(N,v,h,L){Promise.resolve(L).then(function(I){N({value:I,done:h})},v)})(k,_,(C=w[u](C)).done,C.value)})}}};function V(w,g){return g===void 0&&(g=!1),new Promise(function(y,d){var u=g?document.head:document.body,C=document.createElement("script");C.type="text/javascript",C.src=w,C.crossOrigin="anonymous",C.onreadystatechange=y,C.onload=y,C.onerror=d,u.appendChild(C)})}var E=function(w,g){return g===void 0&&(g={}),m(void 0,void 0,void 0,function(){var y,d,u,C,k;return S(this,function(_){switch(_.label){case 0:return y=g.baseUrl,d=y===void 0?"":y,u=g.lastLoadResult,C=g.inHead,k=C!==void 0&&C,[4,Promise.all(w.map(function(N){return m(void 0,void 0,void 0,function(){var v,h,L,I,O,G,oe,ae;return S(this,function(se){switch(se.label){case 0:return v=N.name,h=N.path,L=N.deps,(oe={})[v]=!0,I=oe,(ae={})[v]=!1,O=ae,window[v]?[2,I]:[3,1];case 1:return G=!0,L&&u&&[].concat(L).forEach(function(fe){u[fe]!==!1&&(G=!0)}),G?[4,V(h.indexOf("http")===0||h.indexOf("//:")===0?h:d+h,k).then(function(){return I}).catch(function(){return O})]:[3,3];case 2:return[2,se.sent()];case 3:return[2,O]}})})}))];case 1:return[2,_.sent()]}})})},F=function(w,g){return g===void 0&&(g={}),function(){var y=[].concat(l(w));return{next:function(){if(y.length){var d=y.shift();return E(d,g).then(function(u){return{value:u,done:!1}})}return Promise.resolve({done:!0})}}}},x=function(w,g){var y;return g===void 0&&(g={}),(y={})[Symbol.asyncIterator]=F(w,g),y},A=function(w,g){return g===void 0&&(g={}),m(void 0,void 0,void 0,function(){var y,d,u,C,k,_;return S(this,function(N){switch(N.label){case 0:N.trys.push([0,5,6,11]),y=P(x(w,g)),N.label=1;case 1:return[4,y.next()];case 2:if((d=N.sent()).done)return[3,4];u=d.value,g.lastLoadResult=g.lastLoadResult||{},console.log("current load: ",u),u.forEach(function(v){g.lastLoadResult=c(c({},g.lastLoadResult),v)}),N.label=3;case 3:return[3,1];case 4:return[3,11];case 5:return C=N.sent(),k={error:C},[3,11];case 6:return N.trys.push([6,,9,10]),d&&!d.done&&(_=y.return)?[4,_.call(y)]:[3,8];case 7:N.sent(),N.label=8;case 8:return[3,10];case 9:if(k)throw k.error;return[7];case 10:return[7];case 11:return[2,g.lastLoadResult]}})})}}])})})(Pe);var nn=Pe.exports;const rn={key:0,class:"ai-assistant"},on={name:"AiChat"},an=e.defineComponent({...on,props:{token:{type:String,default:""},identifier:{type:String,default:""},baseUrl:{type:String,default:""},title:{type:String,default:"数智AI助理"},llmName:{type:String,default:"szjy"},messagePostRender:{type:Function,default:null},extraConfig:{type:Object,default:()=>({})},soundBaseUrl:{type:String,default:"/sounds/"},workerUrl:{type:String,default:""}},setup(o){const t=e.ref(!1),s=e.ref(!1),r=()=>{t.value=!t.value},a=()=>{s.value=!0,t.value=!1},n=c=>{console.log("用户输入:",c)},i=[{name:"markdownit",path:"markdown-it.min.js"},{name:"hljs",path:"highlight.11.11.1.min.js"}];let l={};return nn.loadScriptsQueue(i,{baseUrl:"/scripts/ai/",lastLoadResult:l,inHead:!1}).then(c=>{if(console.log("load ai deps: ",c),window.markdownit){const m=window.markdownit();console.log("markdownit: ",m),et()}}),(c,m)=>s.value?e.createCommentVNode("",!0):(e.openBlock(),e.createElementBlock("div",rn,[e.createVNode(tn,{modelValue:t.value,"onUpdate:modelValue":m[0]||(m[0]=S=>t.value=S),onSubmit:n,token:o.token,identifier:o.identifier,baseUrl:o.baseUrl,title:o.title,llmName:o.llmName,messagePostRender:o.messagePostRender,extraConfig:o.extraConfig,soundBaseUrl:o.soundBaseUrl,workerUrl:o.workerUrl},null,8,["modelValue","token","identifier","baseUrl","title","llmName","messagePostRender","extraConfig","soundBaseUrl","workerUrl"]),e.createElementVNode("div",{class:"ai-icon",onClick:r},[e.createElementVNode("div",{class:"close-icon",onClick:e.withModifiers(a,["stop"])},[...m[1]||(m[1]=[e.createElementVNode("svg",{viewBox:"0 0 1024 1024",width:"8",height:"8"},[e.createElementVNode("path",{d:"M512 456.310154L94.247385 38.557538a39.384615 39.384615 0 0 0-55.689847 55.689847L456.310154 512 38.557538 929.752615a39.384615 39.384615 0 0 0 55.689847 55.689847L512 567.689846l417.752615 417.752616c15.163077 15.163077 40.526769 15.163077 55.689847 0s15.163077-40.526769 0-55.689847L567.689846 512l417.752616-417.752615a39.384615 39.384615 0 0 0-55.689847-55.689847L512 456.310154z",fill:"currentColor"})],-1)])]),m[2]||(m[2]=e.createElementVNode("img",{src:q,alt:"AI助手"},null,-1)),m[3]||(m[3]=e.createElementVNode("span",{class:"ai-icon-text"},"AI助手",-1))])]))}}),Ae=ve(an,[["__scopeId","data-v-0c5630f1"]]),Be=Object.freeze(Object.defineProperty({__proto__:null,SzAiChat:Ae},Symbol.toStringTag,{value:"Module"})),me=function(o){if(!me.installed){me.installed=!0;for(let t in Be){const s=Reflect.get(Be,t);o.component(s.name,s)}}},sn=(o,t)=>{const s=t?`?${new URLSearchParams(t).toString()}`:"";console.log(`点击了路由链接: ${o}${s}`)},Le=o=>{const t=o.indexOf("?");if(t===-1)return{routeName:o};const s=o.substring(0,t),r=o.substring(t+1),a={};return new URLSearchParams(r).forEach((i,l)=>{a[l]=i}),{routeName:s,queryParams:Object.keys(a).length>0?a:void 0}},ln={color:"#536fec",fontWeight:"bold",textDecoration:"underline",cursor:"pointer",padding:"0 3px"},Me=o=>{const t=/#router:([^#]+)#/g,s=[];let r=0,a;for(;(a=t.exec(o))!==null;){a.index>r&&s.push({text:o.substring(r,a.index)});const n=a[1],{routeName:i,queryParams:l}=Le(n);s.push({text:i,routeName:i,queryParams:l}),r=t.lastIndex}return r<o.length&&s.push({text:o.substring(r)}),s},Ue=(o,t,s={},r)=>{const{onRouteClick:a=sn,linkStyle:n={}}=s,i=document.createElement("a");i.href="#",i.textContent=o;const l={...ln,...n};return Object.assign(i.style,l),i.addEventListener("click",c=>{c.preventDefault(),a(t,r)}),i},Fe=o=>{const t=/#router:([^#]+)#/g,s=[],r=document.createTreeWalker(o,NodeFilter.SHOW_TEXT,null);let a=r.nextNode();for(;a;){const n=a,i=n.textContent||"";if(t.test(i)){t.lastIndex=0;const l=Me(i);l.length>0&&s.push({node:n,replacements:l})}a=r.nextNode()}return s},cn=(o,t,s={})=>{const r=Fe(o);r.forEach(({node:a,replacements:n})=>{var l;const i=document.createDocumentFragment();n.forEach(({text:c,routeName:m,queryParams:S})=>{if(m){const P=Ue(c,m,s,S);i.appendChild(P)}else i.appendChild(document.createTextNode(c))}),(l=a.parentNode)==null||l.replaceChild(i,a)}),s!=null&&s.nodeCallback&&r.forEach(({node:a,replacements:n})=>{var i;(i=s.nodeCallback)==null||i.call(s,a,n)})},Q="szjy-voice-models",ne="szjy-voice-cache-v1";function K(){return typeof navigator<"u"&&!!navigator.storage&&typeof navigator.storage.getDirectory=="function"}async function re(o=Q){if(!K())return null;try{return await(await navigator.storage.getDirectory()).getDirectoryHandle(o,{create:!0})}catch(t){return console.warn("[OPFS] 获取目录失败,将使用降级缓存:",t),null}}async function dn(o,t,s=Q){if(K())try{const r=await re(s);if(r){const n=await(await r.getFileHandle(o,{create:!0})).createWritable();return await n.write(t),await n.close(),!0}}catch(r){console.warn(`[OPFS] 写入文件 ${o} 失败:`,r)}if(typeof caches<"u")try{const r=await caches.open(ne),a=new Response(t,{headers:{"Content-Type":"application/octet-stream"}});return await r.put(`/${s}/${o}`,a),!0}catch(r){console.warn(`[CacheStorage] 缓存写入 ${o} 失败:`,r)}return!1}async function un(o,t=Q){if(K())try{const s=await re(t);if(s)return await(await(await s.getFileHandle(o,{create:!1})).getFile()).arrayBuffer()}catch{}if(typeof caches<"u")try{const r=await(await caches.open(ne)).match(`/${t}/${o}`);if(r)return await r.arrayBuffer()}catch{}return null}async function hn(o,t=Q){if(K())try{const s=await re(t);if(s)return(await(await s.getFileHandle(o,{create:!1})).getFile()).size>0}catch{}if(typeof caches<"u")try{return!!await(await caches.open(ne)).match(`/${t}/${o}`)}catch{}return!1}async function mn(o=Q){let t=!1;if(K())try{await(await navigator.storage.getDirectory()).removeEntry(o,{recursive:!0}),t=!0,console.log(`[OPFS] 成功清空语音模型缓存目录: ${o}`)}catch(s){s.name==="NotFoundError"?t=!0:console.warn(`[OPFS] 清理目录 ${o} 异常:`,s)}if(typeof caches<"u")try{const s=await caches.keys();for(const r of s)(r.includes("transformers")||r.includes("szjy-voice")||r===ne)&&(await caches.delete(r),t=!0)}catch(s){console.warn("[CacheStorage] 清除缓存异常:",s)}return t}const fn="0.1.10",pn="Sz";function gn({componentPrefix:o=pn,components:t=[]}={}){const s=[];function r(n,i,l){n.component(o+i)||n.component(o+i,l)}function a(n){s.includes(n)||(s.push(n),t.forEach(i=>{const{name:l,alias:c}=i;r(n,l,i),c&&c.forEach(m=>{r(n,m,i)})}))}return{version:fn,componentPrefix:o,install:a}}const yn={install(o){me(o)}};b.AudioRecorder=Ne,b.DEFAULT_WHISPER_WORKER_URL=ue,b.SzAiChat=Ae,b.VoiceInputManager=Ve,b.clearVoiceModelCache=mn,b.create=gn,b.createRouteLink=Ue,b.decodeAudioFile=xe,b.default=yn,b.findRouteTextNodes=Fe,b.float32ToWav=ee,b.getFileFromCache=un,b.getOPFSDirectory=re,b.hasFileInCache=hn,b.isOPFSSupported=K,b.parseRouteMarkerContent=Le,b.parseRouteMarkers=Me,b.resampleAudioData=ie,b.routeLinkRender=cn,b.saveFileToCache=dn,Object.defineProperties(b,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPFS (Origin Private File System) 缓存管理器
|
|
3
|
+
* 提供端侧模型的高性能文件系统持久化存储、读取、校验与清理能力
|
|
4
|
+
* 当环境不支持 OPFS 时,自动降级至 CacheStorage / 内存
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* 检查当前浏览器环境是否支持 OPFS
|
|
8
|
+
*/
|
|
9
|
+
export declare function isOPFSSupported(): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* 获取或创建指定名称的 OPFS 子目录
|
|
12
|
+
*/
|
|
13
|
+
export declare function getOPFSDirectory(dirName?: string): Promise<FileSystemDirectoryHandle | null>;
|
|
14
|
+
/**
|
|
15
|
+
* 保存文件到本地缓存(OPFS 优先,降级 CacheStorage)
|
|
16
|
+
*/
|
|
17
|
+
export declare function saveFileToCache(fileName: string, data: ArrayBuffer | Uint8Array | Blob, dirName?: string): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* 从本地缓存获取文件(OPFS 优先,降级 CacheStorage)
|
|
20
|
+
*/
|
|
21
|
+
export declare function getFileFromCache(fileName: string, dirName?: string): Promise<ArrayBuffer | null>;
|
|
22
|
+
/**
|
|
23
|
+
* 检查指定文件是否已存在于本地缓存中且非空
|
|
24
|
+
*/
|
|
25
|
+
export declare function hasFileInCache(fileName: string, dirName?: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* 清除本地语音模型缓存(同时清理 OPFS 与 CacheStorage)
|
|
28
|
+
* 供用户或开发者重置模型、解决下载中断或异常
|
|
29
|
+
*/
|
|
30
|
+
export declare function clearVoiceModelCache(dirName?: string): Promise<boolean>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 录音采集与 16kHz 单声道重采样模块
|
|
3
|
+
* 专为 Whisper 端侧语音识别设计
|
|
4
|
+
*/
|
|
5
|
+
export interface RecorderOptions {
|
|
6
|
+
sampleRate?: number;
|
|
7
|
+
onVolumeChange?: (volume: number) => void;
|
|
8
|
+
/** 每次采集到 16kHz PCM 分片时回调(与内部缓存共享引用,调用方如需 Transferable 请先拷贝) */
|
|
9
|
+
onAudioChunk?: (chunk: Float32Array) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare class AudioRecorder {
|
|
12
|
+
private targetSampleRate;
|
|
13
|
+
private audioContext;
|
|
14
|
+
private mediaStream;
|
|
15
|
+
private sourceNode;
|
|
16
|
+
private processorNode;
|
|
17
|
+
private audioChunks;
|
|
18
|
+
private onVolumeChange?;
|
|
19
|
+
private onAudioChunk?;
|
|
20
|
+
private _isRecording;
|
|
21
|
+
constructor(options?: RecorderOptions);
|
|
22
|
+
get isRecording(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* 开始录音
|
|
25
|
+
*/
|
|
26
|
+
start(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* 停止录音并返回完整的 16kHz Float32Array 音频数据
|
|
29
|
+
*/
|
|
30
|
+
stop(): Promise<Float32Array>;
|
|
31
|
+
/**
|
|
32
|
+
* 取消录音并丢弃采集的数据
|
|
33
|
+
*/
|
|
34
|
+
cancel(): void;
|
|
35
|
+
private cleanup;
|
|
36
|
+
/**
|
|
37
|
+
* 线性插值音频重采样
|
|
38
|
+
*/
|
|
39
|
+
private resampleAudio;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 线性插值音频重采样
|
|
43
|
+
*/
|
|
44
|
+
export declare function resampleAudioData(audioData: Float32Array, fromSampleRate: number, toSampleRate: number): Float32Array;
|
|
45
|
+
/**
|
|
46
|
+
* 解析并解码音频/视频文件 (WAV, MP4, MP3, M4A 等) 为 16kHz 单声道 Float32Array
|
|
47
|
+
*/
|
|
48
|
+
export declare function decodeAudioFile(file: File | Blob, targetSampleRate?: number): Promise<Float32Array>;
|
|
49
|
+
/**
|
|
50
|
+
* 将 16kHz 单声道 Float32Array PCM 数据编码为标准 WAV 格式 Blob
|
|
51
|
+
*/
|
|
52
|
+
export declare function float32ToWav(samples: Float32Array, sampleRate?: number): Blob;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 语音输入调度中枢 (VoiceInputManager)
|
|
3
|
+
* 统一管理录音、Worker 线程通信、模型加载进度、状态机及结果回调
|
|
4
|
+
*/
|
|
5
|
+
export type VoiceStatus = 'idle' | 'downloading' | 'loading' | 'ready' | 'recording' | 'transcribing' | 'error';
|
|
6
|
+
export interface VoiceProgressInfo {
|
|
7
|
+
status: string;
|
|
8
|
+
progress?: number;
|
|
9
|
+
file?: string;
|
|
10
|
+
loaded?: number;
|
|
11
|
+
total?: number;
|
|
12
|
+
text?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface VoiceManagerOptions {
|
|
15
|
+
soundBaseUrl?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Whisper Worker 脚本地址。不传时自动探测:
|
|
18
|
+
* 1) 相对库入口的 dist/assets 产物(npm link / @fs)
|
|
19
|
+
* 2) 宿主 public 目录 /scripts/ai/whisper.worker.js
|
|
20
|
+
* 3) Vite 打包注入的 URL
|
|
21
|
+
*/
|
|
22
|
+
workerUrl?: string;
|
|
23
|
+
remoteHost?: string;
|
|
24
|
+
modelId?: string;
|
|
25
|
+
language?: string;
|
|
26
|
+
onStatusChange?: (status: VoiceStatus, message?: string) => void;
|
|
27
|
+
onProgress?: (info: VoiceProgressInfo) => void;
|
|
28
|
+
onVolumeChange?: (volume: number) => void;
|
|
29
|
+
onAudioRecorded?: (audioUrl: string, blob: Blob) => void;
|
|
30
|
+
/** 流式中间文本(已确认分片 + 当前分片正在生成的字) */
|
|
31
|
+
onPartial?: (text: string) => void;
|
|
32
|
+
onResult?: (text: string) => void;
|
|
33
|
+
onError?: (error: string) => void;
|
|
34
|
+
}
|
|
35
|
+
/** 宿主项目复制 public 后的稳定 Worker 路径(与 markdown-it 等静态脚本同目录) */
|
|
36
|
+
export declare const DEFAULT_WHISPER_WORKER_URL = "/scripts/ai/whisper.worker.js";
|
|
37
|
+
export declare class VoiceInputManager {
|
|
38
|
+
private recorder;
|
|
39
|
+
private worker;
|
|
40
|
+
private status;
|
|
41
|
+
private options;
|
|
42
|
+
private isReady;
|
|
43
|
+
private initPromise;
|
|
44
|
+
private currentTaskId;
|
|
45
|
+
private pcmParts;
|
|
46
|
+
private pcmLength;
|
|
47
|
+
private pcmSent;
|
|
48
|
+
private streamBusy;
|
|
49
|
+
private streamFinalPending;
|
|
50
|
+
private streamChunkIndex;
|
|
51
|
+
private committedText;
|
|
52
|
+
private chunkPartialText;
|
|
53
|
+
private streamPumpTimer;
|
|
54
|
+
constructor(options?: VoiceManagerOptions);
|
|
55
|
+
get currentStatus(): VoiceStatus;
|
|
56
|
+
get ready(): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* 初始化语音引擎(延迟加载,仅在首次使用或调用时触发)
|
|
59
|
+
*/
|
|
60
|
+
init(customBaseUrl?: string): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* 开始语音录入
|
|
63
|
+
*/
|
|
64
|
+
startRecording(): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* 停止录音并触发模型端侧推理
|
|
67
|
+
*/
|
|
68
|
+
stopAndTranscribe(): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* 直接对外部传入的 16kHz Float32Array 音频进行端侧推理(例如文件上传)
|
|
71
|
+
*/
|
|
72
|
+
transcribeAudioData(audioBuffer: Float32Array, customAudioUrl?: string): Promise<void>;
|
|
73
|
+
/**
|
|
74
|
+
* 上传音频/视频文件(支持 mp4, wav, mp3, m4a 等)并在浏览器端解析识别
|
|
75
|
+
*/
|
|
76
|
+
transcribeFile(file: File | Blob): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* 取消当前录音并丢弃
|
|
79
|
+
*/
|
|
80
|
+
cancelRecording(): void;
|
|
81
|
+
/**
|
|
82
|
+
* 取消当前的语音识别推理任务
|
|
83
|
+
*/
|
|
84
|
+
cancelTranscribe(): void;
|
|
85
|
+
/**
|
|
86
|
+
* 清除本地模型缓存
|
|
87
|
+
*/
|
|
88
|
+
clearCache(): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* 销毁并释放所有资源
|
|
91
|
+
*/
|
|
92
|
+
destroy(): void;
|
|
93
|
+
private startStreamPump;
|
|
94
|
+
private stopStreamPump;
|
|
95
|
+
private getNextChunkSize;
|
|
96
|
+
private resetStreamState;
|
|
97
|
+
private appendPcm;
|
|
98
|
+
private mergePcm;
|
|
99
|
+
private copyPcm;
|
|
100
|
+
private emitLiveText;
|
|
101
|
+
private finishStream;
|
|
102
|
+
/**
|
|
103
|
+
* 将未发送的 PCM 按固定窗口送给 Worker。
|
|
104
|
+
* isFinal=true 表示采集已结束,发完剩余尾巴后收口。
|
|
105
|
+
*/
|
|
106
|
+
private tryDispatchStreamChunk;
|
|
107
|
+
private handleWorkerMessage;
|
|
108
|
+
private setStatus;
|
|
109
|
+
}
|